首页
统计
关于
Search
1
Sealos3.0离线部署K8s集群
1,082 阅读
2
类的加载
741 阅读
3
Spring Cloud OAuth2.0
726 阅读
4
SpringBoot自动装配原理
691 阅读
5
集合不安全问题
584 阅读
笔记
Java
多线程
注解和反射
JVM
JUC
设计模式
Mybatis
Spring
SpringMVC
SpringBoot
MyBatis-Plus
Elastic Search
微服务
Dubbo
Zookeeper
SpringCloud
Nacos
Sentinel
数据库
MySQL
Oracle
PostgreSQL
Redis
MongoDB
工作流
Activiti7
Camunda
消息队列
RabbitMQ
前端
HTML5
CSS
CSS3
JavaScript
jQuery
Vue2
Vue3
Linux
容器
Docker
Kubernetes
Python
登录
Search
标签搜索
Java
CSS
mysql
RabbitMQ
JavaScript
Redis
JVM
Mybatis-Plus
Camunda
多线程
CSS3
Python
Spring Cloud
注解和反射
Activiti
工作流
SpringBoot
Mybatis
Spring
html5
蘇阿細
累计撰写
388
篇文章
累计收到
4
条评论
首页
栏目
笔记
Java
多线程
注解和反射
JVM
JUC
设计模式
Mybatis
Spring
SpringMVC
SpringBoot
MyBatis-Plus
Elastic Search
微服务
Dubbo
Zookeeper
SpringCloud
Nacos
Sentinel
数据库
MySQL
Oracle
PostgreSQL
Redis
MongoDB
工作流
Activiti7
Camunda
消息队列
RabbitMQ
前端
HTML5
CSS
CSS3
JavaScript
jQuery
Vue2
Vue3
Linux
容器
Docker
Kubernetes
Python
页面
统计
关于
搜索到
2
篇与
的结果
2021-04-29
服务熔断
1、环境搭建1、启动Nacos、Sentinel2、新建9003、9004两个模块pom<!-- API --> <dependency> <groupId>com.sw</groupId> <artifactId>cloud-api-commons</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <!-- Nacos --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <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.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency>ymlserver: port: 9003 spring: application: name: nacos-payment-provider cloud: nacos: discovery: server-addr: localhost:8848 management: endpoints: web: exposure: include: '*'启动类@SpringBootApplication @EnableDiscoveryClient public class PaymentMain9003 { public static void main(String[] args) { SpringApplication.run(PaymentMain9003.class, args); } }controller(此处的虚拟数据库是为了方便演示)@RestController @RequestMapping("/payment") public class PaymentController { @Value("${server.port}") private String serverPort; public static Map<Long, Payment> map = new HashMap<>(); static { map.put(1L, new Payment(1L, "螺蛳粉01")); map.put(2L, new Payment(2L, "螺蛳粉02")); map.put(3L, new Payment(3L, "螺蛳粉03")); } @GetMapping("/{id}") public CommonResult<Payment> payment(@PathVariable("id")Long id){ Payment payment = map.get(id); CommonResult<Payment> result = new CommonResult<>(200, "serverPort: " + serverPort, payment); return result; } }注:9004构建步骤与9003一致2、新建8884模块pom同理9004、9004模块ymlserver: port: 8884 spring: application: name: nacos-order-consumer cloud: nacos: discovery: server-addr: localhost:8848 sentinel: transport: # sentinel dashboard地址 dashboard: localhost:8080 # 默认8719端口,如果8719被占用,默认递增 port: 8719 service-url: nacos-user-service: http://nacos-payment-provider management: endpoints: web: exposure: include: '*'启动类@SpringBootApplication @EnableDiscoveryClient public class OrderMain84 { public static void main(String[] args) { SpringApplication.run(OrderMain84.class, args); } }config配置类@Configuration public class ApplicationContextConfig { @Bean @LoadBalanced public RestTemplate getRestTemplate(){ return new RestTemplate(); } }controller@RestController @RequestMapping("/consumer") public class CircleBreakerController { public static final String SERVICE_URL = "http://nacos-payment-provider"; @Autowired private RestTemplate restTemplate; @GetMapping(value = "fallback/{id}", produces = {"application/json;charset=UTF-8"}) @SentinelResource("fallback") public CommonResult<Payment> fallback(@PathVariable("id")Long id){ CommonResult<Payment> result = restTemplate.getForObject(SERVICE_URL + "/payment/" + id, CommonResult.class, id); if (id ==4){ throw new IllegalArgumentException("参数异常!"); }else if (result.getData() == null){ throw new NullPointerException("没有找到对应id的记录!"); } return result; } }指定降级方法@RestController @RequestMapping("/consumer") public class CircleBreakerController { public static final String SERVICE_URL = "http://nacos-payment-provider"; @Autowired private RestTemplate restTemplate; @GetMapping(value = "fallback/{id}", produces = {"application/json;charset=UTF-8"}) //@SentinelResource("fallback") @SentinelResource(value = "fallback", fallback = "handlerFallback") //fallback只负责业务异常 public CommonResult<Payment> fallback(@PathVariable("id")Long id){ CommonResult<Payment> result = restTemplate.getForObject(SERVICE_URL + "/payment/" + id, CommonResult.class, id); if (id ==4){ throw new IllegalArgumentException("参数异常!"); }else if (result.getData() == null){ throw new NullPointerException("没有找到对应id的记录!"); } return result; } public CommonResult handlerFallback(@PathVariable("id")Long id, Throwable e){ Payment payment = new Payment(id, "null"); return new CommonResult(444,"handlerFallback,异常内容:" + e.getMessage(), payment); } }2、测试启动测试:注:此处没有使用Sentinel来配置降级规则,但却降级成功,是因为fallback用于管理异常,当业务发生异常时,可以降级到指定的方法为业务添加blockhandler@RestController @RequestMapping("/consumer") public class CircleBreakerController { public static final String SERVICE_URL = "http://nacos-payment-provider"; @Autowired private RestTemplate restTemplate; @GetMapping(value = "fallback/{id}", produces = {"application/json;charset=UTF-8"}) //@SentinelResource("fallback") //@SentinelResource(value = "fallback", fallback = "handlerFallback") //fallback只负责业务异常 @SentinelResource(value = "fallback", blockHandler = "blockHandler") //blockHandler只负责sentinel控制台的配置 public CommonResult<Payment> fallback(@PathVariable("id")Long id){ CommonResult<Payment> result = restTemplate.getForObject(SERVICE_URL + "/payment/" + id, CommonResult.class, id); if (id ==4){ throw new IllegalArgumentException("参数异常!"); }else if (result.getData() == null){ throw new NullPointerException("没有找到对应id的记录!"); } return result; } // public CommonResult handlerFallback(@PathVariable("id")Long id, Throwable e){ // Payment payment = new Payment(id, "null"); // return new CommonResult(444,"handlerFallback,异常内容:" + e.getMessage(), payment); // } public CommonResult blockHandler(@PathVariable("id")Long id, BlockException exception){ Payment payment = new Payment(id, "null"); return new CommonResult(444,"blockHandler,异常内容:" + exception.getMessage(), payment); } }测试结果:注:可以看到返回结果直接报错,并没有降级,所以说blockHandler只适用于Sentinel配置的规则同时配置fallback和blockHandler@RestController @RequestMapping("/consumer") public class CircleBreakerController { public static final String SERVICE_URL = "http://nacos-payment-provider"; @Autowired private RestTemplate restTemplate; @GetMapping(value = "fallback/{id}", produces = {"application/json;charset=UTF-8"}) //@SentinelResource("fallback") //@SentinelResource(value = "fallback", fallback = "handlerFallback") //fallback只负责业务异常 //@SentinelResource(value = "fallback", blockHandler = "blockHandler") //blockHandler只负责sentinel控制台的配置 @SentinelResource(value = "fallback", fallback = "handlerFallback", blockHandler = "blockHandler") public CommonResult<Payment> fallback(@PathVariable("id")Long id){ CommonResult<Payment> result = restTemplate.getForObject(SERVICE_URL + "/payment/" + id, CommonResult.class, id); if (id ==4){ throw new IllegalArgumentException("参数异常!"); }else if (result.getData() == null){ throw new NullPointerException("没有找到对应id的记录!"); } return result; } public CommonResult handlerFallback(@PathVariable("id")Long id, Throwable e){ Payment payment = new Payment(id, "null"); return new CommonResult(444,"handlerFallback,异常内容:" + e.getMessage(), payment); } public CommonResult blockHandler(@PathVariable("id")Long id, BlockException exception){ Payment payment = new Payment(id, "null"); return new CommonResult(444,"blockHandler,异常内容:" + exception.getMessage(), payment); } } 配置Sentinel规则:结果:可以看到,同时配置fallback和blockHandler,blockHandler的优先级更高exceptionsToIgnore属性@RestController @RequestMapping("/consumer") public class CircleBreakerController { public static final String SERVICE_URL = "http://nacos-payment-provider"; @Autowired private RestTemplate restTemplate; @GetMapping(value = "fallback/{id}", produces = {"application/json;charset=UTF-8"}) //@SentinelResource("fallback") //@SentinelResource(value = "fallback", fallback = "handlerFallback") //fallback只负责业务异常 //@SentinelResource(value = "fallback", blockHandler = "blockHandler") //blockHandler只负责sentinel控制台的配置 @SentinelResource(value = "fallback", fallback = "handlerFallback", blockHandler = "blockHandler", exceptionsToIgnore = {IllegalArgumentException.class}) public CommonResult<Payment> fallback(@PathVariable("id")Long id){ CommonResult<Payment> result = restTemplate.getForObject(SERVICE_URL + "/payment/" + id, CommonResult.class, id); if (id ==4){ throw new IllegalArgumentException("参数异常!"); }else if (result.getData() == null){ throw new NullPointerException("没有找到对应id的记录!"); } return result; } public CommonResult handlerFallback(@PathVariable("id")Long id, Throwable e){ Payment payment = new Payment(id, "null"); return new CommonResult(444,"handlerFallback,异常内容:" + e.getMessage(), payment); } public CommonResult blockHandler(@PathVariable("id")Long id, BlockException exception){ Payment payment = new Payment(id, "null"); return new CommonResult(444,"blockHandler,异常内容:" + exception.getMessage(), payment); } }测试结果:注:使用exceptionsToIgnore指定异常类,表示当前方法如果抛出了指定的异常,不进行降级处理,直接返回抛出的异常结果图片来源:尚硅谷 - 周阳 - Spring Cloud Alibaba
2021年04月29日
44 阅读
0 评论
0 点赞
2020-12-31
Hystrix服务熔断
Hystrix服务熔断服务熔断:熔断机制是对应雪崩效应的一种微服务链路保护机制。当某个微服务不可用或响应时间太长,会进行服务的降级,进而熔断该节点微服务的调用,快速返回“错误的响应信息”,当该节点的调用恢复正常之后注册中心将其恢复至调用链路。Spring Cloud的熔断机制通过Hystrix实现,它会监控微服务间的调用状况,当失败的调用到一定阈值(缺省5秒内20次调用失败),就会启动熔断机制。具体实例:1、导入依赖<dependencies> <!--需要拿到实体类,配置api module--> <dependency> <groupId>com.sw</groupId> <artifactId>springcloud-api</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-core</artifactId> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jetty</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> <version>1.4.7.RELEASE</version> </dependency> <!--actuator监控信息--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <!--Hystrix--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix</artifactId> <version>1.4.7.RELEASE</version> </dependency> </dependencies>2、daopackage com.sw.springcloud.dao; import com.sw.springcloud.pojo.Dept; import org.apache.ibatis.annotations.Mapper; import org.springframework.stereotype.Repository; import java.util.List; /** * @Author suaxi * @Date 2020/12/28 21:34 */ @Mapper @Repository public interface DeptDao { public boolean addDept(Dept dept); public Dept findDept(Long id); public List<Dept> findAll(); } 3、Service接口package com.sw.springcloud.service; import com.sw.springcloud.pojo.Dept; import java.util.List; /** * @Author suaxi * @Date 2020/12/28 21:34 */ public interface DeptService { public boolean addDept(Dept dept); public Dept findDept(Long id); public List<Dept> findAll(); } Service实现:package com.sw.springcloud.service; import com.sw.springcloud.dao.DeptDao; import com.sw.springcloud.pojo.Dept; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; /** * @Author suaxi * @Date 2020/12/28 21:42 */ @Service public class DeptServiceImpl implements DeptService{ @Autowired private DeptDao deptDao; @Override public boolean addDept(Dept dept) { return deptDao.addDept(dept); } @Override public Dept findDept(Long id) { return deptDao.findDept(id); } @Override public List<Dept> findAll() { return deptDao.findAll(); } } 4、controller注:hystrix熔断需开启注解@HystrixCommand(fallbackMethod = "hystrixGet"),且提供熔断后的备选方法package com.sw.springcloud.controller; import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; import com.sw.springcloud.pojo.Dept; import com.sw.springcloud.service.DeptService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.discovery.DiscoveryClient; 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.RestController; import java.util.List; /** * @Author suaxi * @Date 2020/12/28 21:44 * 提供RestFul服务 */ @RestController public class DeptController { @Autowired private DeptService deptService; @GetMapping("/dept/get/{id}") @HystrixCommand(fallbackMethod = "hystrixGet") public Dept get(@PathVariable("id")Long id){ Dept dept = deptService.findDept(id); if (dept==null){ throw new RuntimeException("不存在id为"+id+"的用户,或者信息无法找到"); } return dept; } //熔断后的备选方法 public Dept hystrixGet(@PathVariable("id")Long id){ Dept dept = deptService.findDept(id); return new Dept() .setDeptno(id) .setDname("不存在id为"+id+"的用户,或者信息无法找到,null-->@Hystrix") .setDb_source("No message in MySQL"); } } 5、SpringBoot启动类开启Hystrix注解支持package com.sw.springcloud; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; /** * @Author suaxi * @Date 2020/12/28 21:49 */ @SpringBootApplication @EnableEurekaClient //服务启动后自动注册到Eureka中 @EnableDiscoveryClient //开启服务发现 @EnableCircuitBreaker //开启熔断器支持 public class DeptProviserHystrix_8088 { public static void main(String[] args) { SpringApplication.run(DeptProviserHystrix_8088.class,args); } } 6、appliction.yml配置(此处以单个节点配置为例,实际开发中的微服务节点不止一个)server: port: 8088 #mybatis配置 mybatis: type-aliases-package: com.sw.springcloud.pojo config-location: classpath:mybatis/mybatis-config.xml mapper-locations: classpath:mybatis/mapper/*.xml #Spring配置 spring: application: name: springcloud-provider-dept datasource: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/db01?useUnicode=true&character=UFT-8 username: root password: 123456 #配置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-provider_dept-hystrix_8088 #修改Eureka默认描述信息 #info配置 info: app.name: springcloud-demo company.name: suaxi 当整个微服务调用出现问题时,前端反馈给用户的信息不是错误代码,而是熔断后的备选方法中定义的信息(即快速返回出现错误的响应信息)。用户正常查询信息:查询数据库中不存在的信息,即服务调用出现异常:
2020年12月31日
182 阅读
0 评论
0 点赞