一、服务提供者和服务消费者
名词 | 概念 |
---|---|
服务提供者 | 服务的被调用方 |
服务消费者 | 服务的调用方 |
服务提供者
提供接口服务后,并注册到注册中心。
服务消费者
我们创建了注册中心,以及服务的提供者,并成功地将服务提供者注册到了注册中心上。
要想消费服务是很简单的,我们只需要使用RestTemplate即可,或者例如HttpClient之类的http工具也是可以的。
在集群环境下,我们必然是每个服务部署多个实例,那么“服务消费者”消费“服务提供者”时的负载均衡就是关键。
二、负载均衡器
Ribbon
Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡算法,将Netflix的中间层服务连接在一起。Ribbon客户端组件提供一系列完善的配置项如连接超时,重试等。简单的说,就是在配置文件中列出Load Balancer后面所有的机器,Ribbon会自动的帮助你基于某种规则(如简单轮询,随机连接等)去连接这些机器。我们也很容易使用Ribbon实现自定义的负载均衡算法。简单地说,Ribbon是一个客户端负载均衡器。
Ribbon工作时分为两步:第一步先选择 Eureka Server, 它优先选择在同一个Zone且负载较少的Server;第二步再根据用户指定的策略,在从Server取到的服务注册列表中选择一个地址。其中Ribbon提供了多种策略,例如轮询、随机、根据响应时间加权等。
Feign
Feign是一个声明式的web service客户端,它使得编写web service客户端更为容易。创建接口,为接口添加注解,即可使用Feign。Feign可以使用Feign注解或者JAX-RS注解,还支持热插拔的编码器和解码器。Spring Cloud为Feign添加了Spring MVC的注解支持,并整合了Ribbon和Eureka来为使用Feign时提供负载均衡。
三、 项目基础配置
为实现ribbon负载均衡,需要几个基础的module
- eureka-server,作为eureka的server服务注册中心
- service-provider-1,eureka-client端,连接到eureka-server成为服务提供者1。
- service-provider-2,eureka-client端,连接到eureka-server成为服务提供者2。和service-provider-1提供相同的接口。
eureka-server
eureka的服务端基本配置,参考实战(2)的内容,端口为8761。
service-provider
有2个,内容一样,提供的端口分别为8001和8002。
1、pom.xml依赖
1 | <dependency> |
2、增加注解@EnableDiscoveryClient,即可将service-provider服务注册到Eureka上面去。
3、yml配置中,两个项目的spring.application.name需要保持一致,均为service-provider。
1 | server: |
4、UserController接口,返回的文本可做区分service1和service2,以便ribbon负载时区别开来。
1 |
|
5、访问测试
- 访问http://localhost:8001/1 返回service1
- 访问http://localhost:8002/1 返回service2
四、Ribbon项目配置
1、pom.xml依赖
1 | <dependency> |
2、启动类中,增加注解@EnableDiscoveryClient,即可将service-provider服务注册到Eureka上面去。并使用@LoadBalanced注解,为RestTemplate开启负载均衡的能力。
1 |
|
3、yml配置中,项目的spring.application.name为service-consumer-ribbon,端口8010。
1 | server: |
4、RibbonController.java,请求地址中,service-provider是服微服务的虚拟主机名,Ribbon会自动将虚拟主机名映射成微服务的ip。虚拟主机名不能包含“_”等字符,Ribbon调用时会报错。
1 |
|
5、测试
需要先依次启动项目基础配置中的3个module。才能启动ribbon项目。
- 访问http://localhost:8010/ribbon/1 会间隔返回service1和service2。
- 访问http://localhost:8010/ribbon/log-instance 会在项目日志中打印调用的ip和端口,8001和8002间隔出现。
- 访问http://localhost:8761 可以看到2个SERVICE-PROVIDER和一个SERVICE-CONSUMER-RIBBON。
五、Ribbon配置自定义
java代码自定义Ribbon配置
在SpringCloud中,Ribbon的默认配置如下:(BeanType beanName:Classname)
- IClientConfig ribbonClientConfig: DefaultClientConfigImpl
- IRule ribbonRule: ZoneAvoidanceRule
- IPing ribbonPing: DummyPing
- …
1、如需要改负载均衡规则,可先编写配置类
1 | //配置类,不应该被@ComponentScan扫描 |
2、添加RibbonClient注解,可自定义指定名称Ribbon客户端的配置
1 |
|
3、也可使用@RibbonClients注解为所有Ribbon Client提供默认配置
1 |
属性自定义Ribbon配置
1、针对service-provider的负载均衡规则
1 | service-provider: |
2、针对所有Ribbon Client的负载均衡规则
1 | ribbon: |
3、属性配置的方式比Java代码配置的方式优先级更高
脱离Eureka使用Ribbon
可通过配置ribbon.listOfServers来设置Ribbon客户端设置请求的列表地址
1 | service-provider: |
饥饿加载
Ribbon Client维护了一个子应用程序的上下文,默认是懒加载的,因此首次请求往往会比较慢。可配置饥饿加载,对client1,client2的Ribbon Client在启动时就加载上下文,提高首次请求的速度。
1 | ribbon: |
六、Feign项目配置
『Feign』是Netflix开发的声明式、模板化的HTTP客户端,相比ribbon能更加便捷和优雅的调用HTTP API。
Spring Cloud对Feign进行了增强,支持SpringMVC注解,并整合了Ribbon和Eureka,同时使用Ribbon的客户端侧负载均衡。
1、pom.xml依赖
1 | <dependency> |
2、启动类中,增加注解@EnableDiscoveryClient
即可将service-provider服务注册到Eureka上面去。
增加@EnableFeignClients,启用Feign。
3、yml配置中,项目的spring.application.name为service-consumer-feign,端口8011。
1 | server: |
4、FeignController.java,使用@FeignClient(“service-provider”)注解绑定service-provider服务,还可以使用url参数指定一个URL
1 |
|
5、UserFeignClient.java
1 |
|
6、测试
需要先依次启动项目基础配置中的3个module。才能启动feign项目。
- 访问http://localhost:8011/feign/1 会间隔返回service1和service2。
- 访问http://localhost:8761 可以看到2个SERVICE-PROVIDER和一个SERVICE-CONSUMER-FEIGN。
七、Feign配置自定义
java代码自定义配置
1、Feign的配置类
1 | public class FeignConfiguration { |
2、Feign接口使用原生注解
1 |
|
3、也可通过注解指定默认的配置类,来实现全局配置
1 |
属性自定义配置
1 |
|
属性配置的优先级比java代码配置方式,优先级更高。
Feign构造多参数请求
1、GET请求多参数
1 |
|
1 |
|
2、POST请求多参数
1 |
|
其他特性
- Feign支持继承,但官方不建议,会造成客户端和服务器端代码的紧耦合。
- Feign支持压缩,使用属性feign.compression.request.enabled=true和feign.compression.response.enabled=true
- Feign对日志的处理,分为full、none、basic和headers共4种。
- Feign支持上传文件,需使用feign子项目feign-form来实现。