查看原文
其他

SpringCloud 三种服务调用方式

点击关注 👉 Java架构师技术 2023-09-18
以下文章来源Java架构师技术,回复”Spring“获惊喜礼包
上一篇推文:干掉满屏的 try-catch,这样写太香了!

大家好,我是Java架构师

  • 服务测试环境
    • 1.引入Eureka所需的依赖
    • 2.修改配置文件
    • 3.启动服务
    • 4.测试
  • 消费者
    • 1.发现客户端方式
    • 2.Ribbon方式功能的Spring RestTemplate
    • 3.feign客户端方式



本文主要介绍SpringCloud中调用服务的方式:

  • Spring DiscoveryClient
  • 支持 Ribbon 的 RestTemplate
  • Feign客户端

服务测试环境

测试中,发现Netflix的Eureka服务层采用。

主要步骤如下:

1.引入Eureka所需的依赖

<!--eureka服务端--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka-server</artifactId> </dependency><!--客户端--><dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId></dependency>

2.修改配置文件

服务端:

eureka: instance: hostname: eureka9001.com #eureka服务端的实例名称 instance-id: eureka9001client: register-with-eureka: false #false表示不向注册中心注册自己 fetch-registry: false # #false 表示自己就是注册中心,职责就是维护服务实例,并不需要去检索服务 service-url: defaulteZone: http://127.0.0.1:9001

客户端1:

server: port: 8002spring: application: name: licensingserviceeureka: instance: instance-id: licensing-service-8002 prefer-ip-address: true client: register-with-eureka: true fetch-registry: true service-url: defaultZone: http://127.0.0.1:9001/eureka/,

客户端2:

server: port: 8002spring: application: name: licensingserviceeureka: instance: instance-id: licensing-service-8002 prefer-ip-address: true client: register-with-eureka: true fetch-registry: true service-url: defaultZone: http://127.0.0.1:9001/eureka/,

一组微服务的不同实例采办服务名称不同,不同的实例ID不同,不同,spring.application.nameeureka.instance.instance-id

3.启动服务

服务端:

@SpringBootApplication@EnableEurekaServerpublic class EurekaServerPort9001_App { public static void main(String[] args) { SpringApplication.run(EurekaServerPort9001_App.class,args); }}

客户端:

@SpringBootApplication@RefreshScope@EnableEurekaClientpublic class LicenseApplication_8002 { public static void main(String[] args) { SpringApplication.run(LicenseApplication_8002.class, args); }}

4.测试

进入到Eureka服务端地址,我这是127.0.0.1:9001,可以查看注册到注册中心的服务。

标签:

注意:Eureka通过两次服务检测均到通过,服务将在间隔10秒内成功启动服务注册等待30秒。


消费者

1.发现客户端方式

服务中既是服务是微信也可以是调用者,消费者配置和上面配置的大体参考一致,依赖及配置服务端启动方式EnableEurekaClient:监听启动。

@SpringBootApplication@EnableEurekaClient@EnableDiscoveryClientpublic class ConsumerApplication_7002 { public static void main(String[] args) { SpringApplication.run(ConsumerApplication_7002.class, args); }}

核心配置类:

@Componentpublic class ConsumerDiscoveryClient {
@Autowired private DiscoveryClient discoveryClient;
public ServiceInstance getServiceInstance() { List<ServiceInstance> serviceInstances = discoveryClient.getInstances("licensingservice"); if (serviceInstances.size() == 0) { return null; } return serviceInstances.get(0); }
public String getUrl(String url) { ServiceInstance serviceInstance=this.getServiceInstance(); if (serviceInstance==null) throw new RuntimeException("404 ,NOT FOUND"); String urlR=String.format(url,serviceInstance.getUri().toString()); return urlR; }}

通过DiscoveryClient从尤里卡中获取licensingservice服务的实例,并返回第一个实例。

测试控制器

@RestController@RequestMapping("test")public class TestController { //注意必须new,否则会被ribbon拦截器拦截,改变URL行为 private RestTemplate restTemplate=new RestTemplate(); @Autowired private ConsumerDiscoveryClient consumerDiscoveryClient; @RequestMapping("/getAllEmp") public List<Emp> getAllLicense(){ String url=consumerDiscoveryClient.getUrl("%s/test/getAllEmp"); return restTemplate.getForObject(url,List.class); }}

测试:

  1. 调试信息

从该图可以看到licensingservice,拥有两个服务实例,并可以查看实例信息。

  1. 页面返回信息

成功查询到数据库存储信息。

2.Ribbon方式功能的Spring RestTemplate

同上。

核心配置类:

//指明负载均衡算法@Beanpublic IRule iRule() { return new RoundRobinRule();}
@Bean@LoadBalanced //告诉Spring创建一个支持Ribbon负载均衡的RestTemplatepublic RestTemplate restTemplate() { return new RestTemplate();}

设置均衡方式为轮询方式。

测试类:

@RestController@RequestMapping("rest")public class ConsumerRestController {
@Autowired private RestTemplate restTemplate; private final static String SERVICE_URL_PREFIX = "http://LICENSINGSERVICE";
@RequestMapping("/getById") public Emp getById(Long id) { MultiValueMap<String, Object> paramMap = new LinkedMultiValueMap<String, Object>(); paramMap.add("id", id); return restTemplate.postForObject(SERVICE_URL_PREFIX + "/test/getById", paramMap, Emp.class); }}

测试结果:

第一次:


第二次:

第三次:

因为采用轮询平均方式分别使用不同的服务实例,未区别,将名称确定了一定的。

这上面,Ribbon 是对第一种方式的封装方式和不同的负载率。 Feign的方式则大大降低了开发客户端和提升速度。

3.feign客户端方式

引入依赖:

<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-feign</artifactId></dependency>

主要代码:

@FeignClient(value = "LICENSINGSERVICE",fallbackFactory = ServiceImp.class)public interface ServiceInterface {
@RequestMapping("/test/getById") Emp getById(@RequestParam("id") Long id);
@RequestMapping("/test/getLicenseById") License getLicenseById(@RequestParam("id") Long id);
@RequestMapping("/test/getAllEmp") List<Emp> getAllLicense();}@Componentpublic class ServiceImp implements FallbackFactory<ServiceInterface> {
@Override public ServiceInterface create(Throwable throwable) { return new ServiceInterface() { @Override public Emp getById(Long id) { Emp emp = new Emp(); emp.setName("i am feign fallback create"); return emp; }
@Override public License getLicenseById(Long id) { return null; }
@Override public List<Emp> getAllLicense() { return null; } }; }}

注采用接口模式,通过指定服务名以及方法,在服务开发结果不佳时,方便返回默认的,而不是一个不友好的错误。

主启动类:

@SpringBootApplication@EnableEurekaClient@EnableFeignClientspublic class Consumer_feign_Application_7004 { public static void main(String[] args) { SpringApplication.run(Consumer_feign_Application_7004.class, args); }}

测试类:

@RestController@RequestMapping("rest")public class ConsumerRestController { @Autowired private ServiceInterface serviceInterface;
@Autowired private RestTemplate restTemplate; @RequestMapping("/getById") public Emp getById(Long id) { return serviceInterface.getById(id); }}

测试结果:
正常测试:

关闭两个服务实例,模拟服务实例死亡:

Feign除了能简化服务调用,也可以实现当调用的服务失败时,友好的反馈信息。

欢迎大家进行观点的探讨和碰撞,各抒己见。如果你有疑问,也可以找我沟通和交流。扩展:接私活儿

欢迎有需要的同学试试,如果本文对您有帮助,也请帮忙点个 赞 + 在看 啦!❤️

在 GitHub猿 还有更多优质项目系统学习资源,欢迎分享给其他同学吧!

最后,整理了400多套项目,赠送读者。扫码下方二维码,后台回复赚钱即可获取。

--END--

作者:君宝逍遥

来源:blog.csdn.net/qq_21790633/article/details/105182750

版权申明:内容来源网络,版权归原创者所有。除非无法确认,我们都会标明作者及出处,如有侵权烦请告知,我们会立即删除并表示歉意。谢谢!

往期惊喜:

何谓架构?

一个很酷的后台权限管理系统

一个很酷的博客系统

一个很酷的快速开发代码生成器系统

看看人家那 IM 即时通讯系统,那叫一个优雅(附源码)

马斯克晒出Twitter系统架构图

jar包太大?手把手教你分析 Maven 依赖,完成瘦身优化!

这是我见过最好的支付系统!

sql语句优化的30种方法

Web3.0、区块链和韭菜

三种跨域解决方案:HttpClient、注解、网关

妙用Java 8中的 Function接口,消灭if...else(非常新颖的写法)

牛逼啊,这款低代码生成器开源了!


扫码关注我们的Java架构师技术

带你全面深入Java

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存