kaixinfelix 2019-12-30
![SpringCloud+Eureka+Feign+Ribbon的简化搭建流程,加入熔断,网关和Redis缓存[2] SpringCloud+Eureka+Feign+Ribbon的简化搭建流程,加入熔断,网关和Redis缓存[2]](https://cdn.ancii.com/article/image/v1/wr/wY/x-/-xwrYwYTEo0OX-BzynqEHIAJpH3tJkSKJcHRoYXFIDOG3IhPrqMkgOzkFwggxUJfyVtkxIK3YBuNvezz8XgRUgUtSPrQgZ4lC_Ld_CvBZ10.jpg)
consumer的CenterFeign.java,把返回值全部设置为String/**
* 是consumer调用provider(需要指定provider的名字)
* 请求的清单列表:规定调用地址、参数、返回值
* 在正常走通的时候不走CenterFeignFallBack,当provider down的时候走熔断器,相当于是类的try-catch
*/
@FeignClient(name = "provider",fallback = CenterFeignFallBack.class)
public interface CenterFeign {
@GetMapping("/optionData.do")
public String optionData();
@PostMapping("/showEmpData.do")
//Feign:不支持对象传参,所以要用@RequestBody
public String showEmpData(@RequestBody Emp emp);
@PostMapping("/add.do")
public String add(@RequestBody Emp emp);
@PostMapping("/edit.do")
public String edit(@RequestBody Emp emp);
@GetMapping("/del.do")
public String del(@RequestParam("empno") Integer empno);
}CenterFeign.java的同包下创建实现了CenterFeign接口的CenterFeignFallBack.java作为熔断器@Component
public class CenterFeignFallBack implements CenterFeign {
@Override
public String optionData() {
return "provider-optionData-error";
}
@Override
public String showEmpData(Emp emp) {
return "provider-showEmpData-error";
}
@Override
public String add(Emp emp) {
return "provider-add-error";
}
@Override
public String edit(Emp emp) {
return "provider-edit-error";
}
@Override
public String del(Integer empno) {
return "provider-del-error";
}
}consumer的CenterController.java,返回值全改为String@RestController
public class CenterController{
@Resource
private CenterFeign centerFeign;
@GetMapping("/optionData-consumer.do")
public String optionData() {
return centerFeign.optionData();
}
@PostMapping("/showEmpData-consumer.do")
public String showEmpData(@RequestBody Emp emp) {
return centerFeign.showEmpData(emp);
}
@PostMapping("/add-consumer.do")
public String add(@RequestBody Emp emp) {
return centerFeign.add(emp);
}
@PostMapping("/edit-consumer.do")
public String edit(@RequestBody Emp emp) {
return centerFeign.edit(emp);
}
@GetMapping("/del-consumer.do")
public String del(@RequestParam("empno") Integer empno) {
return centerFeign.del(empno);
}
}consumer中的配置文件application.properties中有没有开启熔断feign.hystrix.enabled=true,没有的话加上#端口号 server.port=8764 #应用名 spring.application.name=consumer #eureka客户端服务url默认区域 eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/ #开启熔断器 feign.hystrix.enabled=true #下线名称.ribbon.NF加载平衡规则类名,这里先注释 provider.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule
访问http://localhost:8761/
发现所有服务已经注册
![SpringCloud+Eureka+Feign+Ribbon的简化搭建流程,加入熔断,网关和Redis缓存[2] SpringCloud+Eureka+Feign+Ribbon的简化搭建流程,加入熔断,网关和Redis缓存[2]](https://cdn.ancii.com/article/image/v1/wr/wY/x-/-xwrYwYTEo0OX-BzynqEHIAJpH3tJkSKJcHRoYXFIDNw1X5sijxeiFWdmhlj0g4XfF_i0poJZw7-Y4VGLXiMuRK-DSqWl6n-_Em-65K995Y.jpg)
正常走provider没有问题
![SpringCloud+Eureka+Feign+Ribbon的简化搭建流程,加入熔断,网关和Redis缓存[2] SpringCloud+Eureka+Feign+Ribbon的简化搭建流程,加入熔断,网关和Redis缓存[2]](https://cdn.ancii.com/article/image/v1/wr/wY/x-/-xwrYwYTEo0OX-BzynqEHIAJpH3tJkSKJcHRoYXFIDNWfF4JhaUCzoNhX2YKmor1G8RClfw7hBDnwmThJ0yqcTex6ZhclIrSNb8YVVVWBHE.jpg)
![SpringCloud+Eureka+Feign+Ribbon的简化搭建流程,加入熔断,网关和Redis缓存[2] SpringCloud+Eureka+Feign+Ribbon的简化搭建流程,加入熔断,网关和Redis缓存[2]](https://cdn.ancii.com/article/image/v1/wr/wY/x-/-xwrYwYTEo0OX-BzynqEHIAJpH3tJkSKJcHRoYXFIDMnq-77ktRzpjgZwjwxEDsO70sKZRAZ_jSmNkvIMbUDTOHiuCosJYQReUVWjB4kBa4.jpg)
![SpringCloud+Eureka+Feign+Ribbon的简化搭建流程,加入熔断,网关和Redis缓存[2] SpringCloud+Eureka+Feign+Ribbon的简化搭建流程,加入熔断,网关和Redis缓存[2]](https://cdn.ancii.com/article/image/v1/wr/wY/x-/-xwrYwYTEo0OX-BzynqEHIAJpH3tJkSKJcHRoYXFIDNoLQ85UC33DGQJ830649JaL8geyxP7kIJJfNosU7jJsQQ18OibpredTi3Web5RuvU.jpg)
走consumer也没有问题,只是返回的格式是字符串类型,不是json类型,但是没关系,格式还是json的格式,前台该怎么转还能怎么转,不影响
![SpringCloud+Eureka+Feign+Ribbon的简化搭建流程,加入熔断,网关和Redis缓存[2] SpringCloud+Eureka+Feign+Ribbon的简化搭建流程,加入熔断,网关和Redis缓存[2]](https://cdn.ancii.com/article/image/v1/wr/wY/x-/-xwrYwYTEo0OX-BzynqEHIAJpH3tJkSKJcHRoYXFIDOR7zcv1k3eaFgnY2nxdOmAMWnpkLyXP016W2lM-XOJxgE5t2niVr3rLD8AybqgPHs.jpg)
那怎么走容错?
现在手动停止一个provider
![SpringCloud+Eureka+Feign+Ribbon的简化搭建流程,加入熔断,网关和Redis缓存[2] SpringCloud+Eureka+Feign+Ribbon的简化搭建流程,加入熔断,网关和Redis缓存[2]](https://cdn.ancii.com/article/image/v1/wr/wY/x-/-xwrYwYTEo0OX-BzynqEHIAJpH3tJkSKJcHRoYXFIDNkknCu5eOHRbxc2Vj0u5r344cQ_Ln6BetwQotRRDekPyqLR1eQwJVorreNqWR0IqA.jpg)
因为这里我开了负载均衡策略(在consumer中的配置文件中provider.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule),所以有一定几率触发熔断器,
![SpringCloud+Eureka+Feign+Ribbon的简化搭建流程,加入熔断,网关和Redis缓存[2] SpringCloud+Eureka+Feign+Ribbon的简化搭建流程,加入熔断,网关和Redis缓存[2]](https://cdn.ancii.com/article/image/v1/wr/wY/x-/-xwrYwYTEo0OX-BzynqEHIAJpH3tJkSKJcHRoYXFIDM8Rv3EdgeiNg7UPc4p337LBkZMkThbugjajOZu3ESoQKYKel5nuXgZv4YznOv9nvw.jpg)
这就相当于类之间的try-catch,没有熔断器的话这里百分百是报错误代码.那这里我先把负载均衡关掉,在测试有没有走容错,(猜一下,会走吗?)
![SpringCloud+Eureka+Feign+Ribbon的简化搭建流程,加入熔断,网关和Redis缓存[2] SpringCloud+Eureka+Feign+Ribbon的简化搭建流程,加入熔断,网关和Redis缓存[2]](https://cdn.ancii.com/article/image/v1/wr/wY/x-/-xwrYwYTEo0OX-BzynqEHIAJpH3tJkSKJcHRoYXFIDPmg5iOip8QMoccNwzo959WMCFj71uKN3hiPjbBEBO-BHdb3aB4D40MfOG3Soi2Qgg.jpg)
![SpringCloud+Eureka+Feign+Ribbon的简化搭建流程,加入熔断,网关和Redis缓存[2] SpringCloud+Eureka+Feign+Ribbon的简化搭建流程,加入熔断,网关和Redis缓存[2]](https://cdn.ancii.com/article/image/v1/wr/wY/x-/-xwrYwYTEo0OX-BzynqEHIAJpH3tJkSKJcHRoYXFIDMGpKeUoqFQdqxj1s0JiZiZB_g2gtW1LGKddLTq3A_EC6uDwTEO_a8fs_PHQAy6ljA.jpg)
这里我测了这么多次,都没有走熔断,所以显然不走,为何?
因为没有手动设置负载均衡策略的话,默认走的是轮询.机制,啥是Ribbon轮询机制?
简单的说就是有abc三台服务器,正常的情况下走a->b->c,在有一台down了的时候,那台就自动跳过,比如b down了,那么就是a->c
以上,个人理解,若有误请指正,よろしくお願いします~
现在,既然一台服务器工作是没有问题 那我两台provider全部停止呢?
![SpringCloud+Eureka+Feign+Ribbon的简化搭建流程,加入熔断,网关和Redis缓存[2] SpringCloud+Eureka+Feign+Ribbon的简化搭建流程,加入熔断,网关和Redis缓存[2]](https://cdn.ancii.com/article/image/v1/wr/wY/x-/-xwrYwYTEo0OX-BzynqEHIAJpH3tJkSKJcHRoYXFIDNIKgpw0vxS-i7L4zDdUf0qzlY7gDY-ay2rwas_4ikdHqqf_i74vnHv4sOgDMM9Y9w.jpg)
那答案是肯定的,绝壁走容错~~
![SpringCloud+Eureka+Feign+Ribbon的简化搭建流程,加入熔断,网关和Redis缓存[2] SpringCloud+Eureka+Feign+Ribbon的简化搭建流程,加入熔断,网关和Redis缓存[2]](https://cdn.ancii.com/article/image/v1/wr/wY/x-/-xwrYwYTEo0OX-BzynqEHIAJpH3tJkSKJcHRoYXFIDOYnGLtvuZ0V_dxoiFqqA176jilPjiEujf0vlI1_hTqeVuF5NgPnwWWdpg1bOUp2Fo.jpg)
新建模块(Spring initializr)zuul-client
![SpringCloud+Eureka+Feign+Ribbon的简化搭建流程,加入熔断,网关和Redis缓存[2] SpringCloud+Eureka+Feign+Ribbon的简化搭建流程,加入熔断,网关和Redis缓存[2]](https://cdn.ancii.com/article/image/v1/wr/wY/x-/-xwrYwYTEo0OX-BzynqEHIAJpH3tJkSKJcHRoYXFIDPHGyTDq5IhqMUPmbeNWSOGbsvTAgTe9VFBHldmGpiO9TkdNrhfV_2oTbgyFd4Ql-w.jpg)
![SpringCloud+Eureka+Feign+Ribbon的简化搭建流程,加入熔断,网关和Redis缓存[2] SpringCloud+Eureka+Feign+Ribbon的简化搭建流程,加入熔断,网关和Redis缓存[2]](https://cdn.ancii.com/article/image/v1/wr/wY/x-/-xwrYwYTEo0OX-BzynqEHIAJpH3tJkSKJcHRoYXFIDN6wxxRhjPdHWEF6fgswSRDK6n4dCjWoCC2Grec_Z_pRlA5_NGl56L6rk5QLPOzA1U.jpg)
application.properties#网关端口 server.port=8765 #应用名 spring.application.name=zuul #网关路径提供者,后面的**表示:xxx.do zuul.routes.provider=/pro/**/ #网关路径消费者,后面的**表示:xxx.do zuul.routes.consumer=/con/**/
//开启网关代理
@EnableZuulProxy
//开启eureka客户端
@EnableEurekaClient
@SpringBootApplication
public class ZuulClientApplication {
public static void main(String[] args) {
SpringApplication.run(ZuulClientApplication.class, args);
}
}![SpringCloud+Eureka+Feign+Ribbon的简化搭建流程,加入熔断,网关和Redis缓存[2] SpringCloud+Eureka+Feign+Ribbon的简化搭建流程,加入熔断,网关和Redis缓存[2]](https://cdn.ancii.com/article/image/v1/wr/wY/x-/-xwrYwYTEo0OX-BzynqEHIAJpH3tJkSKJcHRoYXFIDM9BBzSOJuOqsV6kaH_vROcWVTwge50C2luVnj_Z0HcmUJ3tdoCbkdnDhyWbrya8ec.jpg)
测试provider
![SpringCloud+Eureka+Feign+Ribbon的简化搭建流程,加入熔断,网关和Redis缓存[2] SpringCloud+Eureka+Feign+Ribbon的简化搭建流程,加入熔断,网关和Redis缓存[2]](https://cdn.ancii.com/article/image/v1/wr/wY/x-/-xwrYwYTEo0OX-BzynqEHIAJpH3tJkSKJcHRoYXFIDNzT_W1CarYQREjf-DPvEfwIm61svWSOBON1nV0-9gSQkmMHRAvsJ1CXHcK9z0PnWc.jpg)
测试consumer
![SpringCloud+Eureka+Feign+Ribbon的简化搭建流程,加入熔断,网关和Redis缓存[2] SpringCloud+Eureka+Feign+Ribbon的简化搭建流程,加入熔断,网关和Redis缓存[2]](https://cdn.ancii.com/article/image/v1/wr/wY/x-/-xwrYwYTEo0OX-BzynqEHIAJpH3tJkSKJcHRoYXFIDM8PR3iBmEqwFEfz4WRuR051oDRNctYK6mWi51Pa0y-PdRdHCdVm_OusWGGF_rcCpc.jpg)
统一了所有客户端的ip地址和端口号,我们只要给不同层级的应用起别名就ok了(就是这里的
)
provider-one模块的pom文件中加入redis依赖<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>provider-one模块的DeptServiceImpl文件,加入@Autowired private RedisTemplate redisTemplate;@Service
public class DeptServiceImpl implements DeptService {
@Autowired
private DeptMapper deptMapper;
@Autowired
private RedisTemplate redisTemplate;
@Override
public Map<String, Object> optionData() {
Map<String, Object> map=new HashMap<>();
List<Map<String, Object>> list = deptMapper.selAllDeptData();
// 定义Redis存储集合的对象
ListOperations<String,Map<String,Object>> redisList = redisTemplate.opsForList();
//拼接Redis中存储数据对应的key
String key = "depts";
//判断Redis中是否有key,没有就说明是第一次访问,将数据放入Redis
if(!redisTemplate.hasKey(key)){
//直接将数据库查询出来的值放入Redis
System.out.println("provider-one-optionData的值已经放入Redis");
redisList.leftPushAll(key,list);
}
map.put("data",list);
return map;
}
}DeptService,返回值变成mappublic interface DeptService {
Map<String,Object> optionData();
}CenterController,把返回值类型改为Mappublic Map<String, Object> optionData() {
return deptService.optionData();
}provider-two的pom.xml中加入redis依赖<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>provider-two模块的DeptServiceImpl文件,加入@Autowired private RedisTemplate redisTemplate;@Service
public class DeptServiceImpl implements DeptService {
@Autowired
private DeptMapper deptMapper;
@Autowired
private RedisTemplate redisTemplate;
@Override
public Map<String, Object> optionData() {
Map<String, Object> map=new HashMap<>();
List<Map<String, Object>> list = deptMapper.selAllDeptData();
// 定义Redis存储集合的对象
ListOperations<String,Map<String,Object>> redisList = redisTemplate.opsForList();
//拼接Redis中存储数据对应的key
String key = "depts";
//判断Redis中是否有key,没有就说明是第一次访问,将数据放入Redis
if(!redisTemplate.hasKey(key)){
//直接将数据库查询出来的值放入Redis
System.out.println("provider-two-optionData的值已经放入Redis");
redisList.leftPushAll(key,list);
}
map.put("data",list);
return map;
}
}DeptService,返回值变成mappublic interface DeptService {
Map<String,Object> optionData();
}CenterController,把返回值类型改为Mappublic Map<String, Object> optionData() {
return deptService.optionData();
}provider-one模块的配置文件application.properties,加入Redis配置#服务端口号 server.port=8762 #应用名 spring.application.name=provider #eureka客户端服务url默认区域 eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/ #数据源驱动类名 spring.datasource.driver-class-name=com.mysql.jdbc.Driver #数据源url spring.datasource.url=jdbc:mysql:///kh75 #数据源用户名 spring.datasource.username=root #数据源密码 spring.datasource.password=admin #后期会写mapper.xml,这里先注释 #mybatis.mapper-locations=classpath:mapper/*.xml #给实体类起别名,同样这里先注释 #mybatis.type-aliases-package=cn.kgc.vo #配置Redis spring.redis.port=6379 #redis所在的主机地址 spring.redis.host=xxx.xxx.xxx spring.redis.database=0
provider-two模块的配置文件application.properties,加入Redis配置#服务端口号 server.port=8763 #应用名 spring.application.name=provider #eureka客户端服务url默认区域 eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/ #数据源驱动类名 spring.datasource.driver-class-name=com.mysql.jdbc.Driver #数据源url spring.datasource.url=jdbc:mysql:///kh75 #数据源用户名 spring.datasource.username=root #数据源密码 spring.datasource.password=admin #后期会写mapper.xml,这里先注释 #mybatis.mapper-locations=classpath:mapper/*.xml #给实体类起别名,同样这里先注释 #mybatis.type-aliases-package=cn.kgc.vo #配置Redis spring.redis.port=6379 #redis所在的主机地址 spring.redis.host=xxx.xxx.xx spring.redis.database=0
consumer的CenterFeign,所有返回值都是map@FeignClient(name = "provider",fallback = CenterFeignFallBack.class)
public interface CenterFeign {
@GetMapping("/optionData.do")
Map<String,Object> optionData();
@PostMapping("/showEmpData.do")
//Feign:不支持对象传参,所以要用@RequestBody
Map<String,Object> showEmpData(@RequestBody Emp emp);
@PostMapping("/add.do")
Map<String,Object> add(@RequestBody Emp emp);
@PostMapping("/edit.do")
Map<String,Object> edit(@RequestBody Emp emp);
@GetMapping("/del.do")
Map<String,Object> del(@RequestParam("empno") Integer empno);
}CenterFeignFallBack@Component
public class CenterFeignFallBack implements CenterFeign {
private Map<String, Object> map = new HashMap<> ();
@Autowired
private RedisTemplate redisTemplate;
@Override
public Map<String,Object> optionData() {
ListOperations<String,Map<String,Object>> redisList = redisTemplate.opsForList();
map.put("msg","provider-optionData-error");
map.put("feign-data",redisList.range("depts",0,-1));
return map;
}
@Override
public Map<String,Object> showEmpData(Emp emp) {
ListOperations<String,Map<String,Object>> redisList = redisTemplate.opsForList();
map.put("msg","provider-showEmpData-error");
//这里对应的serviceImp里面还没修改成Redis,先放着
map.put("feign-data",redisList.range("emps",0,-1));
return map;
}
@Override
public Map<String,Object> add(Emp emp) {
map.put("msg","provider-add-error");
return map;
}
@Override
public Map<String,Object> edit(Emp emp) {
map.put("msg","provider-edit-error");
return map;
}
@Override
public Map<String,Object> del(Integer empno) {
map.put("msg","provider-del-error");
return map;
}
}@RestController
public class CenterController{
@Resource
private CenterFeign centerFeign;
@GetMapping("/optionData-consumer.do")
public Map<String,Object> optionData() {
return centerFeign.optionData();
}
@PostMapping("/showEmpData-consumer.do")
public Map<String,Object> showEmpData(@RequestBody Emp emp) {
return centerFeign.showEmpData(emp);
}
@PostMapping("/add-consumer.do")
public Map<String,Object> add(@RequestBody Emp emp) {
return centerFeign.add(emp);
}
@PostMapping("/edit-consumer.do")
public Map<String,Object> edit(@RequestBody Emp emp) {
return centerFeign.edit(emp);
}
@GetMapping("/del-consumer.do")
public Map<String,Object> del(@RequestParam("empno") Integer empno) {
return centerFeign.del(empno);
}
}![SpringCloud+Eureka+Feign+Ribbon的简化搭建流程,加入熔断,网关和Redis缓存[2] SpringCloud+Eureka+Feign+Ribbon的简化搭建流程,加入熔断,网关和Redis缓存[2]](https://cdn.ancii.com/article/image/v1/wr/wY/x-/-xwrYwYTEo0OX-BzynqEHIAJpH3tJkSKJcHRoYXFIDO5EvqDNB5XXWa6HzMx8dc5_4hoWIR4Nl1mAwUWJvMfFhQyq4L9uhUoNN7PCsZThUg.jpg)
![SpringCloud+Eureka+Feign+Ribbon的简化搭建流程,加入熔断,网关和Redis缓存[2] SpringCloud+Eureka+Feign+Ribbon的简化搭建流程,加入熔断,网关和Redis缓存[2]](https://cdn.ancii.com/article/image/v1/wr/wY/x-/-xwrYwYTEo0OX-BzynqEHIAJpH3tJkSKJcHRoYXFIDN1cWtivX5dhnSgL81vA-d0TmSqx4GS69aiZbpX29aaWa_cUyo19jVY_wqfyj0pfWA.jpg)
![SpringCloud+Eureka+Feign+Ribbon的简化搭建流程,加入熔断,网关和Redis缓存[2] SpringCloud+Eureka+Feign+Ribbon的简化搭建流程,加入熔断,网关和Redis缓存[2]](https://cdn.ancii.com/article/image/v1/wr/wY/x-/-xwrYwYTEo0OX-BzynqEHIAJpH3tJkSKJcHRoYXFIDOTxHu0PLXP9XZuGfJoWAxtTPvCF9tgmeDLM1HtvnGFG3gyew1SEgka568upuGDCz4.jpg)
![SpringCloud+Eureka+Feign+Ribbon的简化搭建流程,加入熔断,网关和Redis缓存[2] SpringCloud+Eureka+Feign+Ribbon的简化搭建流程,加入熔断,网关和Redis缓存[2]](https://cdn.ancii.com/article/image/v1/wr/wY/x-/-xwrYwYTEo0OX-BzynqEHIAJpH3tJkSKJcHRoYXFIDOn2gBBPw7s5oodnnBX8XoQrpQHxt_UL20QZeGP3wL3VqUWDez-2QsOeZ9J1wDbZhg.jpg)
![SpringCloud+Eureka+Feign+Ribbon的简化搭建流程,加入熔断,网关和Redis缓存[2] SpringCloud+Eureka+Feign+Ribbon的简化搭建流程,加入熔断,网关和Redis缓存[2]](https://cdn.ancii.com/article/image/v1/wr/wY/x-/-xwrYwYTEo0OX-BzynqEHIAJpH3tJkSKJcHRoYXFIDNMWZ6pcOU4RGJaX6NK2bwY8fjKQYMjII655ZofF7jOfmQs0MA-QjSQr94OaxxbGQE.jpg)
![SpringCloud+Eureka+Feign+Ribbon的简化搭建流程,加入熔断,网关和Redis缓存[2] SpringCloud+Eureka+Feign+Ribbon的简化搭建流程,加入熔断,网关和Redis缓存[2]](https://cdn.ancii.com/article/image/v1/wr/wY/x-/-xwrYwYTEo0OX-BzynqEHIAJpH3tJkSKJcHRoYXFIDNOsyN1tUynDGo2Se-T5b3InYNbgkaqU4faBb_Mz8iswoin8oCmYywGSlDU2K3oTLs.jpg)
把提供者断掉,理论上走熔断和redis数据
![SpringCloud+Eureka+Feign+Ribbon的简化搭建流程,加入熔断,网关和Redis缓存[2] SpringCloud+Eureka+Feign+Ribbon的简化搭建流程,加入熔断,网关和Redis缓存[2]](https://cdn.ancii.com/article/image/v1/wr/wY/x-/-xwrYwYTEo0OX-BzynqEHIAJpH3tJkSKJcHRoYXFIDP6Q3ZdTEutAaz_DA-9hoDxkOvpsPmNypHQx04mJqdii-qd3if2fFfnMQxfiDyCCY0.jpg)
![SpringCloud+Eureka+Feign+Ribbon的简化搭建流程,加入熔断,网关和Redis缓存[2] SpringCloud+Eureka+Feign+Ribbon的简化搭建流程,加入熔断,网关和Redis缓存[2]](https://cdn.ancii.com/article/image/v1/wr/wY/x-/-xwrYwYTEo0OX-BzynqEHIAJpH3tJkSKJcHRoYXFIDMfGKdo0W2ftZ_fOAYTXATTt2ck4xMJXc9wvpReE_Xrbyb661XVOmdpGVCggopFoFM.jpg)
以上....