服务间通信是指微服务架构中不同服务之间进行数据传输和交互的过程。在微服务架构中,服务之间通常采用 RESTful API、RPC 或消息队列等方式进行通信。
RESTful API 是一种基于 HTTP 协议的 Web 服务架构,它定义了一组规则和约束,使得不同应用程序之间可以通过 HTTP 协议进行通信。在 RESTful API 中,服务之间通过发送 HTTP 请求和响应来实现数据交互,其中请求方法包括 GET、POST、PUT、DELETE 等。RESTful API 通常是无状态的,即每个请求都是独立的,不依赖于之前的请求。
RPC(Remote Procedure Call)是一种远程过程调用协议,它允许一个应用程序通过调用另一个应用程序中的函数或方法来实现跨进程或跨机器的通信。在 RPC 中,应用程序通过发送请求和接收响应来进行数据交互,请求和响应可以使用不同的传输协议和序列化协议,例如 HTTP、TCP、JSON、Protobuf 等。
消息队列是一种异步通信机制,它通过将消息发送到队列中,使得不同应用程序之间可以解耦合地进行通信。在消息队列中,发送方将消息发送到队列中,接收方从队列中获取消息并进行处理。消息队列通常使用消息中间件来实现,例如 RabbitMQ、Kafka 等。
微服务架构中服务之间通信的选择取决于具体的应用场景,通常需要综合考虑可扩展性、可靠性、性能、复杂度等因素。在实际应用中,通常会采用多种通信方式来实现服务间的交互。
服务间的通信:服务从注册中心获取服务列表,然后调用。
自定义完成服务间的通信:了解服务中心的提供的各种接口,然后拉取服务列表,编写代码完成负载均衡
使用现成解决方案:Ribbon
RestTemplate+Ribbon
Ribbon,RestTemplate 依赖
<!--cloud默认就引入,无需显示引入-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
<!--springcloud也默认引入RestTemplate-->
工厂中自动注入Ribbon的DiscoveryClient(服务发现),LoadBalanceClient(负载均衡)对象,直接获取使用即可。
RestTemplate需要自己往容器内注入,或者自己new。
//拉取服务列表
List<ServiceInstance> products = discoveryClient.getInstances("producerOnline");
for (ServiceInstance product : products) {
System.out.print(product.getHost());
System.out.print(product.getPort());
System.out.print(product.getUri());
System.out.println();
}
//根据负载均衡策略选取某一个服务调用
ServiceInstance product = loadBalancerClient.choose("producerOnline"); //负载均衡
//根据筛选的url发送http请求
RestTemplate rest=new RestTemplate();
String forObject = rest.getForObject(product.getUri()+"/index",String.class);
@LoadBalance注解
将上面的过程全部封装,我们直接写url,url的ip端口用服务名称代替,springboot帮助我们拼接。
修饰注入RestTemplate方法,使得RestTamplate具有负载均衡的作用
@Bean
@LoadBalanced //可能是采用aop或者是拦截器,在最终发送的时候进行了url的拼接替换
public RestTemplate restTemplate() {
RestTemplate restTemplate = new RestTemplate();
return restTemplate;
}
@GetMapping("/test2")
String test2(){
//直接用http://producerOnline是不可取的,可以将其防在一个配置类内,从配置文件注入
String forObject = restTemplate.getForObject("http://producerOnline/index", String.class);
return forObject;
}
直接用http://producerOnline是不可取的,springcloud也给出了解决方案。
负载均衡原理(ribbon)
服务id从注册中心拉取服务列表,将服务列表缓存在本地,默认的负载均衡策略是轮询。
负载均衡策略
负载均衡在哪里完成的?可以从LoadBalanceClient入手。
源码:choose==>父接口serviceInstanceChooser(查看实现)==>RibbonLoadBalancerClient==>getServer方法==>loadBalancer.chooseServer()方法==>IloadBalancer类(具体有3个实现,tip:不知道是那个,这个时候可以debug,看看默认走那个类)==>ZoneAwareLoadBalancer==>BaseLoadBalancer==>PredicateBaseRule(IRule)默认是RoundRoBinRule
可以看到是由IRule这个接口实现了负载均衡的规则,查看其看有那些具体实现类,就有具体提供了那些实现方法。
7个策略:
- RoundRobinRule 轮询策略 按顺序循环选择
- RandomRule 随机策略 随机选择
- AvailabilityFilteringRule 可用过滤策略 会先过滤由于多次访问故障而处于断路器跳闸状态的服务,还有并发的连接数量超过阈值的服务(tomcat默认200),然后对剩余的服务列表按照轮询策略进行访问。 先过滤掉非健康的服务实例,然后再选择连接数较小的服务实例 。
- WeightedResponseTimeRule 响应时间加权策略 根据平均响应的时间计算所有服务的权重,响应时间越快服务权重越大被选中的概率越高,刚启动时如果统计信息不足,则使用RoundRobinRule策略,等统计信息足够会切换到。
- RetryRule 重试策略 先按照RoundRobinRule的策略获取服务,如果获取失败则在制定时间内进行重试,获取可用的服务。使用超时策略最好设置一个超时时间。
- BestAviableRule 最低并发策略 会先过滤掉由于多次访问故障而处于断路器跳闸状态的服务,然后选择一个并发量最小的服务
- ZoneAvoidanceRule 区域敏感策略 根据服务所在区域(zone)的性能和服务的可用性来选择服务实例,在没有区域的环境下,该策略和轮询策略类似。
设置负载均衡策略
针对不同的服务使用不同的策略
producerOnline: # 对producerOnline服务使用随机策略
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule #全类名
#com.netflix.loadbalancer.WeightedResponseTimeRule
#com.netflix.loadbalancer.RoundRobinRule
#com.netflix.loadbalancer.RandomRule
#com.netflix.loadbalancer.BestAvailableRule
#com.netflix.loadbalancer.RandomRule
#com.netflix.loadbalancer.AvailabilityFilteringRule
#com.netflix.loadbalancer.ZoneAvoidanceRule
ribbon:
ConnectTimeout: 2000 # 连接的超时时间
ReadTimeout: 5000 # 处理的超时时间