Spring Cloud
单一应用架构 :主要解决ORM 数据库访问层。
垂直应用架构 : 解决分层问题,实现应用的分层开发,提升开发效率。
分布式应用架构:解决系统间调用问题,引发了SOA(面向服务开发)架构新潮。
SOA治理(Macro Service治理):对面向服务开发和治理同时提出新的挑战,要求应用能够做到容易部署、智能路由、服务负载均衡、熔断等要求,能够做到对服务的可视化治理等。
伴随着互联网的发展,人们对这种微服务的开发的呼声越来越大,在互联网的萌芽了两款重量级的SOA治理框架阿里巴巴
Dubbo
和SpringFrameWork提供的SpringCloud
由于Spring的广大使用群体也间接的使的Spring Cloud的市场占用率一路飙升。阿里巴巴的Dubbo
也开始发力,由于阿里巴巴的优秀的技术团队和国内较高的知名度,也对Dubbo
框架的发展起到一定的推广的作用,但是相比较于SpringCloud而言,dubbo由于易用性上和对程序员的要求都比Spring Cloud要高一些,因此目前很多互联网公司在做微服务组件开发的时候一般还是使用SpringCloud
居多。
Spring Cloud Ribbon 组件 -负载均衡
Spring Cloud Ribbon 是一个基于Http和TCP的客服端负载均衡工具,它是基于Netflix Ribbon实现的。通过SpringCloud的自动配置使得项目可以自动的给RestTemplate添加拦截器。
基于配置文件
- 在项目中集成ribbon
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Greenwich.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
....
<!--ribbon-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
</dependencies>
- 配置类中添加@LoadBalanced注解
@SpringBootApplication
public class UserApplciation {
public static void main(String[] args) {
SpringApplication.run(UserApplciation.class,args);
}
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
RestTemplate restTemplate = new RestTemplate();
return restTemplate;
}
}
ribbon底层会将RestTemplate进行加强,实质上是对RestTemplate添加拦截器,用于修改URL中的服务名。
- application.properties
server.port=8887
USER-SERVER.ribbon.listOfServers=localhost:8889,localhost:8888
USER-SERVER.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule
- UserController
@RestController
@RequestMapping(value = "usermanager")
public class UserController {
@Autowired
private RestTemplate restTemplate;
@GetMapping(value = "/queryUserById")
public User queryUserById(@RequestParam(value = "id") Integer id){
String url="http://USER-SERVER/formUserManager/queryUserById?id={id}";
return restTemplate.getForObject(url,User.class,id);
}
}
这里的缺点是服务器的地址是配置死的,一旦配置的服务节点上线|下线都有可能影响本应用,我们期望该
listOfServers
可以动态变更,达到服务节点的热部署。
基于注解类
- RibbonConfigure
@Configuration
public class RibbonConfigure {
@Bean
public ServerList<Server> ribbonServerList(){
Server server1 = new Server("localhost", 8888);
Server server2 = new Server("localhost", 8889);
return new StaticServerList<Server>(server1,server2);
}
@Bean
public IRule ribbonRule(){
return new RandomRule();
}
}
这里的缺点是服务器的地址是配置死的,一旦配置的服务节点上线|下线都有可能影响本应用,我们期望该
ribbonServerList
可以动态变更,达到服务节点的热部署。
- UserApplciation
@SpringBootApplication
@RibbonClient(name = "USER-SERVICE",configuration = {RibbonConfigure.class})
public class UserApplciation {
public static void main(String[] args) {
SpringApplication.run(UserApplciation.class,args);
}
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
RestTemplate restTemplate = new RestTemplate();
return restTemplate;
}
}
- UserController
@RestController
@RequestMapping(value = "usermanager")
public class UserController {
@Autowired
private RestTemplate restTemplate;
@GetMapping(value = "/queryUserById")
public User queryUserById(@RequestParam(value = "id") Integer id){
String url="http://USER-SERVER/formUserManager/queryUserById?id={id}";
return restTemplate.getForObject(url,User.class,id);
}
}
Spring Cloud Eureka (服务注册中心)
Spring Cloud Eureka 是 Spring Cloud Netflix 微服务套件中的一部分, 它基于 Netflix Eureka 做了二次封装, 主要负责完成微服务架构中的服务治理功能。 Spring Cloud 通过为Eureka 增加了 Spring Boot 风格的自动化配置,我们只需通过简单引入依赖和注解配置就能让 Spring Boot构建的微服务应用轻松地与 Eureka 服务治理体系进行整合。
Eureka注册中心集群构建
- pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.5.RELEASE</version>
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Greenwich.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
- 启动配置类
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class,args);
}
}
- application-eureka-1.properties
server.port=1111
# 指定当前注册中心的服务名称
spring.application.name=eurekaregistry
## 启用注册中心主动失效,并且每次主动失效检测间隔为5s 默认值60s
eureka.server.eviction-interval-timer-in-ms= 5000
## 设置eureka注册中心的响应更新时间
eureka.server.responseCacheUpdateIntervalMs=3000
eureka.server.responseCacheAutoExpirationInSeconds=60
## 配置注册中心的主机名
eureka.instance.instance-id = eureka-1
eureka.instance.hostname = CentOSA
## 服务刷新时间配置,每隔这个时间会主动心跳一次
eureka.instance.lease-renewal-interval-in-seconds= 5
## 服务提供者被认定为丢失心跳超时,失效多久后被删除
eureka.instance.lease-expiration-duration-in-seconds=15
## 配置定时获取|抓取注册中心的数据时间
eureka.client.registry-fetch-interval-seconds= 5
eureka.client.instance-info-replication-interval-seconds= 5
## 配置集群中其他eureka实例,用于本eureka实例的注册方。
eureka.client.region=beijing
eureka.client.availability-zones.beijing=zone-2,zone-3
eureka.client.service-url.zone-2=http://CentOSB:1111/eureka/
eureka.client.service-url.zone-3=http://CentOSC:1111/eureka/
- application-eureka-2.properties
server.port=1111
# 指定当前注册中心的服务名称
spring.application.name=eurekaregistry
## 启用注册中心主动失效,并且每次主动失效检测间隔为5s 默认值60s
eureka.server.eviction-interval-timer-in-ms= 5000
## 设置eureka注册中心的响应更新时间
eureka.server.responseCacheUpdateIntervalMs=3000
eureka.server.responseCacheAutoExpirationInSeconds=60
## 配置注册中心的主机名
eureka.instance.instance-id = eureka-2
eureka.instance.hostname = CentOSB
## 服务刷新时间配置,每隔这个时间会主动心跳一次
eureka.instance.lease-renewal-interval-in-seconds= 5
## 服务提供者被认定为丢失心跳超时,失效多久后被删除
eureka.instance.lease-expiration-duration-in-seconds=15
## 配置定时获取|抓取注册中心的数据时间
eureka.client.registry-fetch-interval-seconds= 5
eureka.client.instance-info-replication-interval-seconds= 5
## 配置集群中其他eureka实例,用于本eureka实例的注册方。
eureka.client.region=beijing
eureka.client.availability-zones.beijing=zone-1,zone-3
eureka.client.service-url.zone-1=http://CentOSA:1111/eureka/
eureka.client.service-url.zone-3=http://CentOSC:1111/eureka/
- application-eureka-3.properties
server.port=1111
# 指定当前注册中心的服务名称
spring.application.name=eurekaregistry
## 启用注册中心主动失效,并且每次主动失效检测间隔为5s 默认值60s
eureka.server.eviction-interval-timer-in-ms= 5000
## 设置eureka注册中心的响应更新时间
eureka.server.responseCacheUpdateIntervalMs=3000
eureka.server.responseCacheAutoExpirationInSeconds=60
## 配置注册中心的主机名
eureka.instance.instance-id = eureka-3
eureka.instance.hostname = CentOSC
## 服务刷新时间配置,每隔这个时间会主动心跳一次
eureka.instance.lease-renewal-interval-in-seconds= 5
## 服务提供者被认定为丢失心跳超时,失效多久后被删除
eureka.instance.lease-expiration-duration-in-seconds=15
## 配置定时获取|抓取注册中心的数据时间
eureka.client.registry-fetch-interval-seconds= 5
eureka.client.instance-info-replication-interval-seconds= 5
## 配置集群中其他eureka实例,用于本eureka实例的注册方。
eureka.client.region=beijing
eureka.client.availability-zones.beijing=zone-1,zone-2
eureka.client.service-url.zone-1=http://CentOSA:1111/eureka/
eureka.client.service-url.zone-2=http://CentOSB:1111/eureka/
- Maven package指令打包
mvn package
- 上传eurekacloud-1.0-SNAPSHOT.jar到CentOSA、CentOSB、CentOSC
[root@CentOSA ~]# java -jar eurekacloud-1.0-SNAPSHOT.jar --spring.profiles.active=eureka-1
[root@CentOSB ~]# java -jar eurekacloud-1.0-SNAPSHOT.jar --spring.profiles.active=eureka-2
[root@CentOSC ~]# java -jar eurekacloud-1.0-SNAPSHOT.jar --spring.profiles.active=eureka-3
- 访问浏览器查看Eureka是否启动成功
Eureka自我保护机制
由于Eureka再设计上遵循AP原则,一旦Eureka服务节点检测到异常
Renews < Renews threshold
(心跳阈值< 接收心跳)Eureka会进入自我保护机制。一旦进入自我保护机制,Eureka就会失去剔除失效节点功能(失去检测功能)。
Renews threshold
:eureka.server.renewal-percent-threshold= 0.85
集群: (2 x n) x eureka.server.renewal-percent-threshold = (2 * 3) *0.85 = 5.1 = 取 5
单机: 2 × (n+1) × eureka.server.renewal-percent-threshold = 4 * 0.85 = 3.4 取 3
- 默认自我保护机制是开启的(推荐选项)
eureka.server.enable-self-preservation=true
如果是单机模式很容易触发自我保护,因为
Renews threshold= 2 (1+1) 0.85 = 3
Renews (last min) =( 60 / eureka.instance.lease-renewal-interval-in-seconds=30)* 1 = 2
- 所以如果构建的是单机版本的Eureka,建议大家关闭自我保护机制。
服务提供方注册服务
- 发布服务
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Greenwich.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
- 配置服务发布信息
# 发布服务
spring.application.name=USER-SERVICE
# 发布服务实例id
eureka.instance.instance-id=001
eureka.instance.prefer-ip-address=true
eureka.instance.lease-renewal-interval-in-seconds=10
eureka.instance.lease-expiration-duration-in-seconds=20
# 只单纯的注册服务,并不获取服务注册列表信息
eureka.client.register-with-eureka=true
eureka.client.healthcheck.enabled=true
eureka.client.fetch-registry=false
eureka.client.service-url.defaultZone=http://CentOSA:1111/eureka/,http://CentOSB:1111/eureka/,http://CentOSC:1111/eureka/
服务引用方引用服务
- pom.xml
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Greenwich.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<!--引入 eureka后,无需再次引入Ribbon-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
- application.peroperties
# 只是单纯的获取注册中心的注册信息,并不注册自己
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=true
eureka.client.service-url.defaultZone=http://CentOSA:1111/eureka/,http://CentOSB:1111/eureka/,http://CentOSC:1111/eureka/
Spring Cloud Hystrix (熔断器)
Hystrix是一个延迟和容错库,旨在隔离对远程系统,服务和第三方库的访问点,停止级联故障,并在复杂的分布式系统中实现弹性,在这些系统中,故障是不可避免的。
熔断器集成
- pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.5.RELEASE</version>
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Greenwich.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
</dependencies>
- 在需要熔断的方法是添加@HystrixComand注解
@HystrixCommand
@Override
public Integer sum(Integer x, Integer y) {
System.out.println("thread:"+Thread.currentThread().getId());
int b=10/0;
return (x+y)*2;
}
- 在启动类上添加@EnableCircuitBreaker
@SpringBootApplication
@EnableCircuitBreaker
public class HystrixSpringBootApplication {
public static void main(String[] args) {
SpringApplication.run(HystrixSpringBootApplication.class,args);
}
}
线程隔离
默认该方法的执行会启动新的线程执行和主程序不在一个线程中,因此如果上下文中存在ThreadLocal变量,在该方法中就失效了。因此一般可以通过设置commandProperties注解属性,设置线程就可以了。
@HystrixCommand(commandProperties = {
@HystrixProperty(name = "execution.isolation.strategy",value = "SEMAPHORE")
})
@Override
public User queryUserById(Integer id) {
System.out.println(Thread.currentThread().getId());
return userDAO.queryById(id);
}
execution.isolation.strategy
该属性的可选值有两个THREAD
和SEMAPHORE
默认值是THREAD
.①一般如果一个实例一秒钟有100个并发,此时因为频繁启动线程的开销过大此时一般考虑使用SEMAPHORE,②非网络调用。
Fallback
过在@HystrixCommand中声明fallbackMethod的名称可以实现优雅降级,如下所示:
@HystrixCommand(
fallbackMethod = "failback4Sum",
// ignoreExceptions = {ArithmeticException.class},
commandProperties = {
@HystrixProperty(name="execution.isolation.strategy",value="SEMAPHORE")
}
)
@Override
public Integer sum(Integer x, Integer y) {
System.out.println("thread:"+Thread.currentThread().getId());
int b=10/0;
return (x+y)*2;
}
public Integer failback4Sum(Integer x, Integer y,Throwable e) {
System.out.println(e.getMessage());
return x+y;
}
注意要求fallbackMethod方法和目标方法必须在同一个类中,具有相同的参数(异常参数可选)
请求超时熔断
用户可以通过设置execution.isolation.thread.timeoutInMilliseconds
属性设置一个方法最大请求延迟,系统会抛出HystrixTimeoutException
@HystrixCommand(
fallbackMethod = "failback4Sum",
commandProperties = {
@HystrixProperty(name="execution.isolation.strategy",value="THREAD"),
@HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value = "100")
}
)
@Override
public Integer sum(Integer x, Integer y) {
try {
int ms=new Random().nextInt(200);
System.out.println("sleep:"+ms);
Thread.sleep(ms);
} catch (Exception e) {
System.err.println(e.getMessage());
}
return (x+y)*2;
}
public Integer failback4Sum(Integer x, Integer y,Throwable e) {
return x+y;
}
熔断器限流
hystrix dashbord(监测)
- pom.ml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
- application.properties
# 开启健康检查的所有访问接口
management.endpoints.web.exposure.include=*
- HystrixSpringBootApplication
@SpringBootApplication
@EnableCircuitBreaker
@EnableHystrixDashboard
public class HystrixSpringBootApplication {
public static void main(String[] args) {
SpringApplication.run(HystrixSpringBootApplication.class,args);
}
}
-
完整熔断器配置
@Service
public class UserService implements IUserService {
public User failback4QueryUserById(Integer id) {
return new User(-1,"服务降级!");
}
@HystrixCommand(
fallbackMethod = "failback4QueryUserById",
commandProperties = {
@HystrixProperty(name="execution.isolation.strategy",value="THREAD"),
@HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value = "1000"),
// 时间窗口 必须是 numBuckets的整数倍数
@HystrixProperty(name="metrics.rollingStats.timeInMilliseconds",value = "10000"),//设置窗口长度10秒
@HystrixProperty(name="metrics.rollingStats.numBuckets",value = "10"),//设置窗口滑动间隔1s
//闸刀开启的条件 请求数> 2 && 错误率> 50%
@HystrixProperty(name="circuitBreaker.requestVolumeThreshold",value = "20"),//设置最小请求次数
@HystrixProperty(name="circuitBreaker.errorThresholdPercentage",value = "50"),//设置错误率50%
@HystrixProperty(name="circuitBreaker.sleepWindowInMilliseconds",value = "5000"),// 当全开到半开的时间间隔
},
threadPoolProperties = {
@HystrixProperty(name="coreSize",value="10"),//设置线程池大小
@HystrixProperty(name="queueSizeRejectionThreshold",value = "10")//设置队列最大等待请求数
}
)
@Override
public User queryUserById(Integer id) {
int random = new Random().nextInt(3000);
try {
System.out.println("sleep:"+random);
Thread.sleep(random);
} catch (InterruptedException e) {
}
return new User(id,"user"+id);
}
}
Spring Cloud OpenFeign(Rest客户端)
Feign是一个声明性的Web服务客户端。它使编写Web服务客户端变得更容易。Feign 增加了对Spring MVC注解的支持,并使用了Spring MVC中相同HttpMessageConverters。 Feign集成了Ribbon、Eureka、Hystrix,在使用Feign时提供负载均衡以及容错的的http客户端。
快速入门
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.5.RELEASE</version>
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Greenwich.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
- application.properties
server.port=9999
# 配置Eureka 拦截参数
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=true
eureka.client.healthcheck.enabled=true
eureka.client.service-url.defaultZone=http://CentOSA:1111/eureka/,http://CentOSB:1111/eureka/,http://CentOSC:1111/eureka/
- UserFeignControllerClient
@FeignClient(name = "USER-SERVICE")
public interface UserFeignControllerClient {
@PostMapping(value = "/formUserManager/addUser")
@ResponseBody
public void addUser(User user) throws IOException;
@GetMapping(value = "/formUserManager/queryUserById")
@ResponseBody
public User queryUserById(@RequestParam(value = "id") Integer id);
@GetMapping(value = "/formUserManager/queryUserByPage")
@ResponseBody
public Map<String, Object> queryUserByPage(@RequestParam(value = "page", defaultValue = "1") Integer pageNow,
@RequestParam(value = "rows", defaultValue = "10") Integer pageSize,
@RequestParam(value = "column", required = false) String column,
@RequestParam(value = "value", required = false) String value);
@DeleteMapping(value = "/formUserManager/delteUserByIds")
@ResponseBody
public void delteUserByIds(@RequestParam(value = "ids") Integer[] ids);
@PutMapping(value = "/formUserManager/updateUser")
@ResponseBody
public void updateUser(User user) throws IOException;
}
- FeignSpringBootApplication
@SpringBootApplication
@EnableFeignClients
public class FeignSpringBootApplication {
public static void main(String[] args) {
SpringApplication.run(FeignSpringBootApplication.class,args);
}
}
配置熔断
默认Feign没有开启熔断策略,需要用户在配置文件中指定
- application.properties
server.port=9999
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=true
eureka.client.healthcheck.enabled=true
eureka.client.service-url.defaultZone=http://CentOSA:1111/eureka/,http://CentOSB:1111/eureka/,http://CentOSC:1111/eureka/
# 开启hystrix
feign.hystrix.enabled=true
# 配置服务访问超时
feign.client.config.USER-SERVICE.connect-timeout=100
feign.client.config.USER-SERVICE.read-timeout=100
- 修改UserFeignControllerClient,添加failback属性
@FeignClient(name = "USER-SERVICE",fallback = UserFeignControllerFailBack.class)
public interface UserFeignControllerClient {
@PostMapping(value = "/formUserManager/addUser")
@ResponseBody
public void addUser(User user) throws IOException;
@GetMapping(value = "/formUserManager/queryUserById")
@ResponseBody
public User queryUserById(@RequestParam(value = "id") Integer id);
@GetMapping(value = "/formUserManager/queryUserByPage")
@ResponseBody
public Map<String, Object> queryUserByPage(@RequestParam(value = "page", defaultValue = "1") Integer pageNow,
@RequestParam(value = "rows", defaultValue = "10") Integer pageSize,
@RequestParam(value = "column", required = false) String column,
@RequestParam(value = "value", required = false) String value);
@DeleteMapping(value = "/formUserManager/delteUserByIds")
@ResponseBody
public void delteUserByIds(@RequestParam(value = "ids") Integer[] ids);
@PutMapping(value = "/formUserManager/updateUser")
@ResponseBody
public void updateUser(User user) throws IOException;
}
- UserFeignControllerFailBack
@Component
public class UserFeignControllerFailBack implements UserFeignControllerClient {
@Override
public void addUser(User user) throws IOException {
}
@Override
public User queryUserById(Integer id) {
User user = new User("故障", false, "***", new Date(), "xxxx");
user.setId(id);
return user;
}
@Override
public Map<String, Object> queryUserByPage(Integer pageNow, Integer pageSize, String column, String value) {
return null;
}
@Override
public void delteUserByIds(Integer[] ids) {
}
@Override
public void updateUser(User user) throws IOException {
}
}
Hystrix Dashboard
updateUser")
@ResponseBody
public void updateUser(User user) throws IOException;
}
- UserFeignControllerFailBack
@Component
public class UserFeignControllerFailBack implements UserFeignControllerClient {
@Override
public void addUser(User user) throws IOException {
}
@Override
public User queryUserById(Integer id) {
User user = new User("故障", false, "***", new Date(), "xxxx");
user.setId(id);
return user;
}
@Override
public Map<String, Object> queryUserByPage(Integer pageNow, Integer pageSize, String column, String value) {
return null;
}
@Override
public void delteUserByIds(Integer[] ids) {
}
@Override
public void updateUser(User user) throws IOException {
}
}