一、Feign 自带日志配置 配置到消费者端
1、创建FeignConfig 配置类个级别 我使用的是最全的FULL模式
@Configuration public class FeignConfing { @Bean Logger.Level feignLoggerLevel() { return Logger.Level.FULL; } }
2、在YML 配置开启日志
#开启Feign客户端日志 logging: level: com.cloud.springcloud.service.PaymentFeginService: debug #扫描的是你那个service的类全类名
二、Feign 超时配置
1、配置 在消费端 Feign调用默认就是一秒钟)
默认fegin客户端只等待一秒、但是服务端处理需要等待1秒中、导致fegin客户端不想等待了、直接返回报错、为了避免这样的情况、有时候我们需要设置fegin客户端的超时时间
需要在消费者 yml加入超时配置
#设置fegin客户端超时时间(OpenFegin 默认ribbon) ribbon: #指的是建立连接所用的时间,适用于网络状态正常情况下、两端连接所用的时间 ReadTimeout: 5000 #指的是建立连接后从服务器读取到可用资源所用时间 ConnecTimeout: 5000
三、feign 负载均衡
1、自带负载均衡、不需要配置任何东西、把生产者变成集群、比如 80、81 启动服务后、在88服务下通过Fegin客户端 RPC远程调用即可、可以打印一下端口号、确认是负载均衡
四、Ribbon 负载均衡
1、默认是轮询机制 、配置负载均衡 需要加一个配置类
如果不配置不生效 不加LoadBalanced 注解的话 就会报错、访问集群 他不知道找那个生产者
@Configuration public class ApplicationContextConfig { @Bean @LoadBalanced //8001--8002 集群之后 不知道找那个报错上面的错 需要开启负载均衡器 // LoadBalanced 赋予 RestTemplate 负载均衡的能力 、调用使用的是 RestTemplate public RestTemplate getRestTemplate() { return new RestTemplate(); } }
2、更改 负载的算法 使用随机 添加随机算法的配置类 这个类要放到扫描的同等级目录不能被扫描到
@Configuration public class MySelfRule { /** * 自定义负载均衡 * * @return */ @Bean public IRule myRule() { return new RandomRule(); //随机轮询 } }
然后 在启动类加上 这段注解、代表使用自定义配置、name 就是生产者的集群名称
@RibbonClient(name = "CLOUD-PAYMENT-SERVICE", configuration = MySelfRule.class) //自定义随机
五、禁用自我保护机制 默认是true
1、注册中心 Eureka 配置
eureka: server: enable-self-preservation: false #禁用自我保护模式 eviction-interval-timer-in-ms: 2000 #心跳时间 2秒
比如订单要注册到注册中心、需要在配置 、一秒发一次心跳、检查无心跳、立马剔除服务
instance: instance-id: payment8001 #修改主机名称 prefer-ip-address: true # 设置ip #Eureka客户端向服务端发送心跳的时间间隔、单位为秒(默认30秒) lease-renewal-interval-in-seconds: 1 #Eureka 服务端收到最后一次心跳后等待时间上限、单位为秒(默认90秒),超时将剔除服务 lease-expiration-duration-in-seconds: 2
六、就是配置Eureka 注册中心 注册进来的服务名称 不配置默认是你们电脑的主机名称、不显示ip的 需要配置的 参考 我的 五、禁用自我保护机制 第二个配置 主机名的 就好了 |
七、服务降级
服务器忙、请稍后再试、不让客户端等待并立刻返回一个友好提示,fallback 就是 返回友好提示 说等待几秒再试
那些情况会发现服务降级
① 程序运行异常
② 超时
③ 服务熔断触发降级
④ 线程池/信号量打满也会导致服务降级
一、自定义全局降级 减少配置 —- 消费方 80 设置降级 (调用方)
启动类 上方 加入 @EnableHystrix 注解
YML配置
#开启对feign的支持 feign: hystrix: enabled: true
/** 自定义全局降级 减少配置 * @ClassName HuangXiangXiang * @Date 2020/4/5 17:47 * @Version V1.0 **/ @RestController @Slf4j //@DefaultProperties 第一步 @DefaultProperties(defaultFallback = "payment_Global_FallbackMethod") //全局的faback public class OrderHystirxController { @Resource private PaymentHystrixService paymentHystrixService; /* * 这个是使用全局的降级 */ @GetMapping("/consumer/payment/hystrix/timeout1/{id}") @HystrixCommand // 第二步 加这个注解 public String paymentInfo_TimeOut1(Integer id) { int i = 1 / 0; String result = paymentHystrixService.paymentInfo_TimeOut(id); return result; } //执行峰值时调用 public String paymentInfo_TimeOutHandler(@PathVariable("id") Integer id) { return "我是消费者80,对方支付系统繁忙请10秒钟后再试或者自己运行出错请检查自己,o(╥﹏╥)o"; } /** 第三步 * 自定义全局fallback 方法 */ public String payment_Global_FallbackMethod() { return "Global异常处理信息,请稍后重试,😂"; } }
二、自定义全局降级 减少配置
/** 单独方法设置降级 * @ClassName HuangXiangXiang * @Date 2020/4/5 17:47 * @Version V1.0 **/ @RestController @Slf4j public class OrderHystirxController { @Resource private PaymentHystrixService paymentHystrixService; /** * 单独方法设置降级、客户端请求 3000 秒 相应超过3000 * @param id * @return */ @GetMapping("/consumer/payment/hystrix/timeout2/{id}") @HystrixCommand(fallbackMethod = "paymentInfo_TimeOutHandler", commandProperties = { @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000") }) public String paymentInfo_TimeOut2(Integer id) { int i = 1 / 0; //测试程序出错跳转自定义 String result = paymentHystrixService.paymentInfo_TimeOut(id); return result; } //执行峰值时调用 public String paymentInfo_TimeOutHandler(@PathVariable("id") Integer id) { return "我是消费者80,对方支付系统繁忙请10秒钟后再试或者自己运行出错请检查自己,o(╥﹏╥)o"; } }
三、防止生产者宕机 调用
/** 演示 生产者宕机 调用降级方法 控制器调用 * @ClassName HuangXiangXiang * @Date 2020/4/5 17:47 * @Version V1.0 **/ @RestController @Slf4j public class OrderHystirxController { @Resource private PaymentHystrixService paymentHystrixService; @GetMapping("/consumer/payment/hystrix/ok/{id}") public String paymentInfo_OK(@PathVariable("id") Integer id) { String result = paymentHystrixService.paymentInfo_OK(id); return result; } }
/** 创建第一步 * @auther hxx Fegin客户端 fallback 指引 调用失败的类 * @create 2020-02-20 11:55 */ @FeignClient(value = "CLOUD-PROVIDER-HYSTRIX-PAYMENT", fallback = PaymentFallbackService.class) public interface PaymentHystrixService { @GetMapping("/payment/hystrix/ok/{id}") public String paymentInfo_OK(@PathVariable("id") Integer id); @GetMapping("/payment/hystrix/timeout/{id}") public String paymentInfo_TimeOut(@PathVariable("id") Integer id); }
/** 创建第二步 * @auther 代替 Fallback 方法 通配服务降级 * 测试现在只能 解决 服务端宕机情况下 走进来 程序异常不会进来 * @create 2020-02-20 18:22 */ @Component public class PaymentFallbackService implements PaymentHystrixService { @Override public String paymentInfo_OK(Integer id) { return "-----PaymentFallbackService fall back-paymentInfo_OK ,o(╥﹏╥)o"; } @Override public String paymentInfo_TimeOut(Integer id) { return "-----PaymentFallbackService fall back-paymentInfo_TimeOut ,o(╥﹏╥)o"; } }
八、服务熔断
类比保险丝达到最大服务后,直接拒绝访问、拉闸限电、然后调用服务降级的方法返回友好提示 ----这个融断只要达到最大值访问后、就会断路、返回友好提示、不会再像降级一样让你等待再试 服务降级 --》 进行熔断 --》 恢复调用链路 ①就是保险丝
1 、生产方 熔断演示 (第一种熔断)
/** * @auther 生产方 熔断演示 * @create 2020-02-20 11:15 */ @RestController @Slf4j public class PaymentController { @Resource private PaymentService paymentService; @Value("${server.port}") private String serverPort; /** * 服务熔断 * * @param id * @return */ @GetMapping("/payment/circuit/{id}") public String paymentCircuitBreaker(@PathVariable("id") Integer id) { String result = paymentService.paymentCircuitBreaker(id); log.info("****result: " + result); return result; } }
/** * @auther 自定义熔断 * @create 2020-02-20 11:11 */ @Service public class PaymentService { /** * 服务熔断 * @param id * @return */ @HystrixCommand(fallbackMethod = "paymentCircuitBreaker_fallback", commandProperties = { @HystrixProperty(name = "circuitBreaker.enabled", value = "true"),// 是否开启断路器 @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"),// 请求次数 @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000"), // 时间窗口期 @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "60"),// 失败率达到多少后跳闸 }) public String paymentCircuitBreaker(@PathVariable("id") Integer id) { if (id < 0) { throw new RuntimeException("******id 不能负数"); } String serialNumber = IdUtil.simpleUUID(); return Thread.currentThread().getName() + "\t" + "调用成功,流水号: " + serialNumber; } public String paymentCircuitBreaker_fallback(@PathVariable("id") Integer id) { return "id 不能负数,请稍后再试,/(ㄒoㄒ)/~~ id: " + id; } }
2 、生产方 熔断演示 (第二种熔断)
/** * @auther hxx * @create 2020-02-20 11:15 */ @RestController @Slf4j public class PaymentController { @Resource private PaymentService paymentService; @Value("${server.port}") private String serverPort; @GetMapping("/payment/hystrix/timeout/{id}") public String paymentInfo_TimeOut(@PathVariable("id") Integer id) { String result = paymentService.paymentInfo_TimeOut(id); log.info("*****result: " + result); return result; } }
/** * @auther 设置 请求超过3秒 就走降级、 * @create 2020-02-20 11:11 */ @Service public class PaymentService { @HystrixCommand(fallbackMethod = "paymentInfo_TimeOutHandler", commandProperties = { @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000") }) public String paymentInfo_TimeOut(Integer id) { int age = 10 / 0; try { TimeUnit.MILLISECONDS.sleep(0); } catch (InterruptedException e) { e.printStackTrace(); } return "线程池: " + Thread.currentThread().getName() + " id: " + id + "\t" + "O(∩_∩)O哈哈~" + " 耗时(秒): "; } //执行峰值时调用 public String paymentInfo_TimeOutHandler(Integer id) { return "线程池: " + Thread.currentThread().getName() + " 8001系统繁忙或者运行报错,请稍后再试,id: " + id + "\t" + "o(╥﹏╥)o"; } }
九、服务限流
秒杀高斌发等操作、严禁一窝蜂的过来拥挤、大家排队、一秒中 N个、 有序进行
总结: |
十、网关GateWay
①、yml配置 重点配置转发就是 这四行
– id: payment_routh #payment_route
uri: lb://cloud-payment-service
predicates:
– Path=/payment/get/**server: port: 9527 spring: application: name: cloud-gateway cloud: gateway: discovery: locator: enabled: true #开启从注册中心动态创建路由的功能,利用微服务名进行路由 routes: - id: payment_routh #payment_route #路由的ID,没有固定规则但要求唯一,建议配合服务名 #uri: http://localhost:8001 #匹配后提供服务的路由地址 uri: lb://cloud-payment-service #匹配后提供服务的路由地址 predicates: - Path=/payment/get/** # 断言,路径相匹配的进行路由 - id: payment_routh2 #payment_route #路由的ID,没有固定规则但要求唯一,建议配合服务名 #uri: http://localhost:8001 #匹配后提供服务的路由地址 uri: lb://cloud-payment-service #匹配后提供服务的路由地址 predicates: - Path=/payment/lb/** # 断言,路径相匹配的进行路由 #- After=2020-04-08T22:44:16.090+08:00[Asia/Shanghai] #- Cookie=username,zzyy 访问网关加 这个cookie 不加就报错 防止别人攻击 #- Header=X-Request-Id, \d+ # 请求头要有X-Request-Id属性并且值为整数的正则表达式 eureka: instance: hostname: cloud-gateway-service client: #服务提供者provider注册进eureka服务列表内 service-url: register-with-eureka: true fetch-registry: true defaultZone: http://eureka7001.com:7001/eureka
② 网管服务的 拦截、所有服务都从这里经过、可以设置一些验证
/** 网关必须实现 GlobalFilter, Ordered * @auther hxx * @create 2020-02-21 16:40 */ @Component @Slf4j public class MyLogGateWayFilter implements GlobalFilter, Ordered { @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { log.info("***********come in MyLogGateWayFilter: " + new Date()); String uname = exchange.getRequest().getQueryParams().getFirst("uname"); if (uname == null) { log.info("*******用户名为null,非法用户,o(╥﹏╥)o"); exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE); return exchange.getResponse().setComplete(); } return chain.filter(exchange); } @Override public int getOrder() { return 0; } }
② pom文件
pom文件 <!--gateway--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency>
十一、链路追踪
① 下载 jar网站
https://dl.bintray.com/openzipkin/maven/io/zipkin/java/zipkin-server/2.12.9/
cmd 使用 java -jar 下载的包路径
① 加入 pom
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zipkin</artifactId> </dependency>
② 把需要的服务加入到 上面启动的服务上
yml配置文件
#链路调用 zipkin: base-url: http://localhost:9411 sleuth: sampler: #采样率值介于 0 到 1 之间,1 则表示全部采集 probability: 1
③ 显示链路追踪
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/15546.html