SpringCloud 练习笔记.5Fegin 负载均衡-服务端
Feign是声明式Web Service客户端,它让微服务之间的调用变得更简单,类似controller调用service。
SpringCloud集成了Ribbon和Eureka,可以使用Feigin提供负载均衡的http客户端
调用微服务访问两种方法
- 微服务名字 【ribbon】
- 接口和注解 【feign】
Feign能干什么?
-
Feign旨在使编写Java Http客户端变得更容易
-
前面在使用Ribbon + RestTemplate时,利用RestTemplate对Http请求的封装处理,形成了一套模板化的调用方法。
但是在实际开发中,由于对服务依赖的调用可能不止一处,往往一个接口会被多处调用,所以通常都会针对每个微服务自行封装一个客户端类来包装这些依赖服务的调用。所以,Feign在此基础上做了进一步的封装,由他来帮助我们定义和实现依赖服务接口的定义,在Feign的实现下,我们只需要创建一个接口并使用注解的方式来配置它 (类似以前Dao接口上标注Mapper注解,现在是一个微服务接口上面标注一个Feign注解),即可完成对服务提供方的接口绑定,简化了使用Spring Cloud Ribbon 时,自动封装服务调用客户端的开发量。
Feign默认集成了Ribbon
- 利用Ribbon维护了MicroServiceCloud-Dept的服务列表信息,并且通过轮询实现了客户端的负载均衡,而与Ribbon不同的是,通过Feign只需要定义服务绑定接口且以声明式的方法,优雅而简单的实现了服务调用。
集成Fegin
给模块 springcloud-api 添加Fegin依赖
<!--Feign的依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
<version>1.4.6.RELEASE</version>
</dependency>
新建service包下的 DeptClientService 接口
package com.ung.springcloud.service;
import com.ung.springcloud.pojo.Dept;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import java.util.List;
/**
* @Author ung
* @Description:
*/
//微服务客户端注解,value:指定微服务的名字,这样就可以使Feign客户端直接找到对应的微服务
@FeignClient(value = "SPRINGCLOUD-PROVIDER-DEPT")
public interface DeptClientService {
@GetMapping("/dept/get/{id}")
Dept queryById(@PathVariable("id") Long id);
@PostMapping("/dept/add")
Boolean addDept(@RequestBody Dept dept);
@GetMapping("/dept/list")
List<Dept> queryAll();
}
新建 springcloud-consumer-dept-fegin 模块,配置和java类和 springcloud-consumer-dept-80一样
pom依赖新加fegin 依赖
<?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>springcloud-ung</artifactId>
<groupId>com.ung</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>springcloud-consumer-dept-fegin</artifactId>
<dependencies>
<!--Feign的依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
<dependency>
<groupId>com.ung</groupId>
<artifactId>springcloud-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
<!--Ribbon-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
</dependency>
<!--Eureka: Ribbon需要从Eureka服务中心获取要拿什么-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
</dependencies>
</project>
配置文件 application.yml
server:
port: 80
# Eureka配置
eureka:
client:
service-url: # 从三个注册中心中随机取一个去访问
defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
instance:
instance-id: springcloud-consumer-dept-fegin #修改Eureka上的默认描述信息
spring:
application:
name: springcloud-consumer-dept-fegin
配置类ConfigBean
package com.ung.springcloud.config;
import com.netflix.loadbalancer.AvailabilityFilteringRule;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
/**
* @Author ung
* @Description:
*/
@Configuration
public class ConfigBean {
//配置RestTemplate
@LoadBalanced //配置负载均衡实现RestTemplate
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
/**
* IRule:
* RoundRobinRule 轮询策略
* RandomRule 随机策略
* AvailabilityFilteringRule : 会先过滤掉,跳闸,访问故障的服务~,对剩下的进行轮询~
* RetryRule : 会先按照轮询获取服务~,如果服务获取失败,则会在指定的时间内进行,重试
*/
@Bean
public IRule myRule() {
// return new RandomRule();//使用随机策略
//return new RoundRobinRule();//使用轮询策略
return new AvailabilityFilteringRule();//使用轮询策略
//return new RetryRule();//使用轮询策略 重试
}
}
控制层 使用fegin来调用服务
package com.ung.springcloud.controller;
import com.ung.springcloud.pojo.Dept;
import com.ung.springcloud.service.DeptClientService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import java.util.List;
/**
* @Author ung
* @Description: 消费者的控制器
*/
@RestController
public class DeptConsumerController {
//使用Fegin来调用
private DeptClientService service;
@Autowired
public DeptConsumerController(DeptClientService service) {
this.service = service;
}
@GetMapping("/consumer/dept/get/{id}")
public Dept getById(@PathVariable Long id) {
return service.queryById(id);
}
@PostMapping("/consumer/dept/add")
public Boolean add(@RequestBody Dept dept) {
return service.addDept(dept);
}
@GetMapping("/consumer/dept/list")
public List<Dept> list() {
return service.queryAll();
}
}
启动类 FeginDeptConsumer_80
开启feigin
package com.ung.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
/**
* @Author ung
* @Description:
*/
@SpringBootApplication
@EnableEurekaClient //开启Eureka 客户端
@EnableFeignClients(basePackages = {"com.ung.springcloud"})
public class FeginDeptConsumer_80 {
public static void main(String[] args) {
SpringApplication.run(FeginDeptConsumer_80.class,args);
}
}
最后启动服务 springcloud-consumer-dept-fegin
http://eureka7001.com:7001/
可以在注册中心看到成功注册 服务
继续跟之前一样请求 ,一样的返回正确结果
http://localhost/consumer/dept/list