SpringCloud与微服务Ⅶ --- Feign负载均衡
一.Feign是什么
二.Feign能做什么
Feign旨在编写Java Http客户端更加容易。
Feign集成了Ribbon
利用Ribbon维护了MicroServiceCloud-Dept的服务列表信息,并且通过轮询实现了客户端的负载均衡。而与Ribbon不同的是,
Feign通过接口的方法调用Rest服务(之前是Ribbon+RestTemplate),该请求发送给Eureka服务器(http://MICROSERVICE-DEPT/dept/list),通过feign直接找到服务接口,由于在进行服务调用的时候融合了Ribbon技术,所以也支持负载均衡。
修改microservice-api项目
pom文件修改:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>microservice</artifactId> <groupId>com.wang.springcloud</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>microservice-api</artifactId> <packaging>jar</packaging> <dependencies> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <!-- Feign相关 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-feign</artifactId> </dependency> </dependencies> </project>
package com.wang.springcloud.service; import com.wang.springcloud.entities.Dept; import org.springframework.cloud.netflix.feign.FeignClient; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import java.util.List; /** * * @Description: 修改microservicecloud-api工程,根据已经有的DeptClientService接口 新建 一个实现了FallbackFactory接口的类DeptClientServiceFallbackFactory * @author * @date */ @FeignClient(value = "MICROSERVICE-DEPT") //@FeignClient(value = "MICROSERVICECLOUD-DEPT",fallbackFactory=DeptClientServiceFallbackFactory.class) public interface DeptClientService { @RequestMapping(value = "/dept/get/{id}", method = RequestMethod.GET) public Dept get(@PathVariable("id") long id); @RequestMapping(value = "/dept/list", method = RequestMethod.GET) public List<Dept> list(); @RequestMapping(value = "/dept/add", method = RequestMethod.POST) public boolean add(Dept dept); }
上述工作完成后,使用clean,package重新打包成jar,方便其他项目调用。
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>microservice</artifactId> <groupId>com.wang.springcloud</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>microservice-consumer-dept-feign</artifactId> <dependencies> <dependency><!-- 自己定义的api --> <groupId>com.wang.springcloud</groupId> <artifactId>microservice-api</artifactId> <version>${project.version}</version> </dependency> <dependency><!-- Feign相关 --> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-feign</artifactId> </dependency> <!-- Ribbon相关 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-ribbon</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- 修改后立即生效,热部署 --> <dependency> <groupId>org.springframework</groupId> <artifactId>springloaded</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> </dependency> </dependencies> </project>
@RestController public class DeptController { @Autowired private DeptClientService service; @RequestMapping(value = "/consumer/dept/get/{id}") public Dept get(@PathVariable("id") Long id) { return this.service.get(id); } @RequestMapping(value = "/consumer/dept/list") public List<Dept> list() { return this.service.list(); } @RequestMapping(value = "/consumer/dept/add") public Object add(Dept dept) { return this.service.add(dept); } }
四.
服务器端负载均衡 Nginx
Nginx 基于C语言,快速,性能高5w/s。
Redis 5w/s,RibbatMQ 1.2w/s ApacheActiveMQ 0.6w/s 业务系统,kafka 20w~50w/s大数据,Zuul2.0 200w/s
负载均衡、反向代理,代理后端服务器。隐藏真实地址,防火墙,不能外网直接访问,安全性较高。属于服务器端负载均衡。既请求由 nginx 服务器端进行转发。
客户端负载均衡 Ribbon
Ribbon 是从 eureka 注册中心服务器端上获取服务注册信息列表,缓存到本地,然后在本地实现轮询负载均衡策略。
既在客户端实现负载均衡。
应用场景的区别:
Nginx 适合于服务器端实现负载均衡 比如 Tomcat ,Ribbon 适合与在微服务中 RPC 远程调用实现本地服务负载均衡,比如Dubbo、SpringCloud 中都是采用本地负载均衡。
声明式web服务客户端Feign
Feign 是一个声明web服务客户端, 这便得编写web服务客户端更容易Spring Cloud Netflix 的微服务都是以 HTTP 接口的形式暴露的,所以可以用 Apache 的 HttpClient 或 Spring 的 RestTemplate 去调用,而 Feign 是一个使用起来更加方便的HTTP 客戶端,使用起来就像是调用自身工程的方法,而感觉不到是调用远程方法。
Feign包含了Ribben,有时候有的项目会2个技术一起用在该项目中是因为Feign是远程调用的,Ribbon是做负载均衡的。