springcloud 之 Ribbon Hystrix Feign bus 动态修改配置

news2024/9/17 4:00:48

Ribbon 是微服务架构图中负责负载均衡的 组件。

    @Bean
    @LoadBalanced
    public RestTemplate getRestTemplate() {
        return new RestTemplate();
    }

测试如下:

    //微服务方式 Ribbon方式
    @GetMapping("ribbon/{name}")
    public String RibbonTest(@PathVariable String name) {
//        ip和域名 更换成 微服务名称
        String url = "http://user-service/hello?name="+name;
        String forObject = restTemplate.getForObject(url, String.class);
        return forObject;
    }

Hystrix 熔断:

1、熔断器:当某个服务的失败率达到一定阈值时,Hystrix会打开熔断器,停止对该服务的调用,从而防止故障进一步扩散。熔断器开启后,Hystrix会快速失败并返回备选结果或降级数据,以提高系统的响应速度。
2、资源隔离:Hystrix可以对调用远程服务的线程池进行资源隔离,限制调用分布式服务的资源使用。这样,即使某个服务出现故障,也不会影响其他服务的调用。
3、服务降级:当服务调用失败或资源不足时,Hystrix可以进行降级处理。降级后可以配合降级接口返回托底数据,以保证系统的正常运行。
4、缓存:Hystrix提供了请求缓存和请求合并的实现。通过缓存请求的结果,可以减少对后端服务的调用,提高系统的性能。同时,通过将多个相同类型的请求合并为一个批量请求,可以减少网络开销。
5、监控和告警:Hystrix可以监控服务的调用情况,如调用次数、成功率、响应时间等,并提供告警功能。这样,开发人员可以及时发现并处理潜在的问题。

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>

在application中加入 @EnableCircuitBreaker注解

@EnableDiscoveryClient 
@SpringBootApplication
@EnableCircuitBreaker //开启熔断 hytrix
public class ClientServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(ClientServiceApplication.class, args);
    }

使用方式如下:
方案一: 方法级别的指定

    @GetMapping("ribbon/{name}")
    @HystrixCommand(fallbackMethod = "ribbonTestFail")
    public String RibbonTest(@PathVariable String name) {
//        ip和域名 更换成 微服务名称
        String url = "http://user-service/hello?name="+name;
        String forObject = restTemplate.getForObject(url, String.class);
        return forObject;
    }
//    服务降级处理 配合使用    @HystrixCommand(fallbackMethod = "ribbonTestFail") 入参出入要一和对应方法一直
    public String ribbonTestFail(String name){
        return "请求失败";
    }

方案二 类级别方案的指定:

@RestController
@RequestMapping("client")
@DefaultProperties(defaultFallback = "TestControllerRequestFail") //指定访问失败时的方法
public class TestController {

    //微服务方式 Ribbon方式
    @GetMapping("ribbon/{name}")
    @HystrixCommand
    public String RibbonTest(@PathVariable String name) {
//        ip和域名 更换成 微服务名称
        String url = "http://user-service/hello?name="+name;
        String forObject = restTemplate.getForObject(url, String.class);
        return forObject;
    }

//统一处理,配合 @DefaultProperties(defaultFallback = "TestControllerRequestFail") 来使用
    public String TestControllerRequestFail(){
        return "Controller 请求失败";
    }

yml 配置:

hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 1000
      circuitBreaker:
        errorThresholdPercentage: 50 #触发熔断错误比例阈值,默认值50号
        sleepWindowInMilliseconds: 10000 #熔断后休眠时长,默认值5秒
        requestVolumeThreshold: 10 #熔断触发最小请求次数,默认值是20

Feign

是一个声明式的 HTTP 客户端,它使得编写 HTTP 客户端变得更简单,通过注解和接口的方式定义和调用远程服务。
pom 加入依赖:

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

最佳实践:

创建一个 xxx-api模块。(Feign 模块由被调用端编写)

     <groupId>com.zll</groupId>
    <artifactId>user-api</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
            <version>3.1.5</version>
        </dependency>
    </dependencies>
</project>

用于单独存放,Feign 接口,以及 出入参对象。

@Data
public class User {
    private String name;
    private Integer age;
}

@FeignClient("user-service")
public interface UserControllerApi {
    @GetMapping("/hello")
    public String hello(@RequestParam(name = "name", defaultValue = "unknown user") String name);
    @PostMapping("/save_user")
    public String saveUser(User u);
}

被调用端:
user-service:
加入pom

        <dependency>
		    <groupId>com.zll</groupId>
		    <artifactId>user-api</artifactId>
		    <version>0.0.1-SNAPSHOT</version>
        </dependency>

使用API中的入参出参

@Controller
public class UserController {

    @GetMapping("/hello")
    @ResponseBody
    public String hello(@RequestParam(name = "name", defaultValue = "unknown user") String name) {
        return "Hello " + name;
    }

    @PostMapping("/save_user")
    @ResponseBody
    public String saveUser(User u) {
        return "user will save: name=" + u.getName() + ", age=" + u.getAge();
    }

调用端:
第一步:加入pom

        <dependency>
            <groupId>com.zll</groupId>
            <artifactId>user-api</artifactId>
        </dependency>

第二步:开启feign 扫描

@EnableFeignClients(basePackages={"com.zll.api"}) //开启feign功能 并且加入xxx-api的扫描包路径
@SpringBootApplication(basePackages={"com.zll.client","com.zll.api"})
public class ClientServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(ClientServiceApplication.class, args);
    }

第三步:

public class ClientUserController {
	//引入xxx-api的接口对象
    @Resource
    UserControllerApi userControllerApi;

    @GetMapping("/hello")
    public String hello(@RequestParam(name = "name", defaultValue = "unknown user") String name){
    //像调用方法一下,调用请求接口
        String hello = userControllerApi.hello(name);
        return hello;
    }

    @PostMapping("/save_user")
    public String saveUser(User u){
        //像调用方法一下,调用请求接口
        String s = userControllerApi.saveUser(u);
        return s;
    }

注意,使用该种模式,就不支持服务降级处理。

Gateway

创建一个新Module
在这里插入图片描述
GateWayApplication

@EnableDiscoveryClient
@SpringBootApplication
public class GateWayApplication {
    public static void main(String[] args) {
        SpringApplication.run(GateWayApplication.class, args);
    }
}

pom 部分代码

    <parent>
        <groupId>com.zll</groupId>
        <artifactId>zll-springcloud-demo</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>

  <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
    </dependencies>

yml

server:
  port: 9000
spring:
  application:
    name: api-gateway
  cloud:
    gateway:
      routes:
        - id: user-service-route  #路由id 随意编写
          uri: http://127.0.0.1:9092  #代理服务器地址
          predicates:   #路由断言: 可以匹配映射路径
            - Path=/client/**
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:8000/eureka
#========================选配内容 更具需要来定===================
  instance:
#    服务续约时间 默认30秒
    lease-renewal-interval-in-seconds: 5
#    服务时效时间 默认90秒
    lease-expiration-duration-in-seconds: 5
#    优先使用ip
    prefer-ip-address: true
#============================================================

gateway网关的规则:

添加路径
所有路径加前缀:

spring:
  application:
    name: api-gateway
  cloud:
    gateway:
      routes:
        - id: user-service-route  #路由id 随意编写
          uri: lb://client-service  #微服务服务注册名称。lb 表示loadBalancer
          predicates:
            - Path=/**
          filters:
            - PrefixPath=/client #在路径前面添加  /client

实际下过如下:例如:
访问路径: localhost:9000/hello
实际路径:localhost:9000/client/hello

删除路径

    gateway:
      routes:
        - id: user-service-route  #路由id 随意编写
          uri: lb://client-service #微服务服务注册名称。lb 表示loadBalancer
          predicates:
            - Path=/api/client/**
          filters:
            - StripPrefix=1 #1表示删除一个路径  2表示两个路径
#            - PrefixPath=/client #在路径前面添加  /client

示范入戏
访问路径:http://localhost:9000/api/client/hello
实际路径:http://localhost:9000/client/hello

gateway自定义局部拦截器:

第一步在:yml添加拦截器名称和要拦截的参数 拦截器名称 为 MyParam 拦截参数 name
在这里插入图片描述
第二步:创建 MyParam拦截器:MyParam + GatewayFilterFactory = MyParamGatewayFilterFactory 前缀 MyParam +固定命名方式,否则会报错Unable to find GatewayFilterFactory with name MyParam
在这里插入图片描述
第三步:


/**
 * 局部拦截,需要在yml 的fiter 配置
 * spring:
 *   cloud:
 *     gateway:
 *       routes:
 *           uri: lb://client-service #微服务服务注册名称。lb 表示loadBalancer
 *           predicates:
 *             - Path=/client/**
 *           filters:
 *             - MyParam=name
 */
@Component
public class MyParamGatewayFilterFactory extends AbstractGatewayFilterFactory<MyParamGatewayFilterFactory.Config> {
    public MyParamGatewayFilterFactory() {
        super(Config.class);
    }
    public List<String> shortcutFieldOrder() {
        return Arrays.asList("param");
    }
    public static class Config{
        private String param;
        public String getParam() {
            return param;
        }
        public void setParam(String param) {
            this.param = param;
        }
    }
    @Override
    public GatewayFilter apply(Config config) {
        return ((exchange, chain) ->{
            ServerHttpRequest request = exchange.getRequest();
            if(request.getQueryParams().containsKey(config.param)){
                request.getQueryParams().get(config.param).forEach(item-> System.out.printf("%s==%s",config.param,item));
            }
            return chain.filter(exchange);
        });
    }
}

好了,局部拦截器完成。

gateway全局拦截器:

@Component
public class MyGlobalFilter implements GlobalFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        System.out.println("======================MyGlobalFilter====================");
//        String token = exchange.getRequest().getQueryParams().getFirst("name");
        String token = exchange.getRequest().getHeaders().getFirst("Token");
        if(StringUtils.isBlank(token)){
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            return exchange.getResponse().setComplete();
        }
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        //值越小,执行优先级越高。
        return 100;
    }
}

gateway跨域解决:

在这里插入图片描述
微服务内部,使用feign 外部调用gateway 就用nginx

配置中心

pom

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-config-server</artifactId>
        </dependency>

第二步:
在git 创建一个仓库,任意分支创建一个 user-dev.yml 文件,这里以 master 分支为例
user-dev.yml 中随便写你想要的配置
在这里插入图片描述

例如:

server:
  port: 9091
spring:
  application:
    name: user-server
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:8000/eureka

回到项目的yml中:
配置git 地址

server:
  port: 10000
spring:
  application:
    name: config-server
  cloud:
    config:
      server:
        git:
          uri: https://gitee.com/leonzhang2013/configuration-center.git  #这里写你自己的git 地址
          default-label: master #不写默认值,config会报NoSuchLabelException: No such label: main。
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:8000/eureka

项目中开启配置功能:
在这里插入图片描述
最后启动项目:
访问你编写的git 文件,例如:
在这里插入图片描述
其他项目读取配置:
添加配置pom

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
            <version>2.1.1.RELEASE</version>
        </dependency>

如果报错:
在这里插入图片描述
就再加入下面的包:(新版本这个包被排除了,需要添加这包)

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bootstrap</artifactId>
        </dependency>

更换启动文件:
applicaton.yml ⇒ bootstrap.yml

spring:
  cloud:
    config:
      name: user  # 要与仓库中配置的profile保持一致  例如 user-dev.yml
      profile: dev # 要与仓库中配置的profile保持一致  例如 user-dev.yml
      label: master #分支名称
      discovery:
        enabled: true
        service-id: config-server #配置中心的名称

eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:8000/eureka

启动配置中心和注册中心服务,最后启动项目,就可以完美读到配置了。项目运行正常
user-server 读到配置,端口为配置的9091
在这里插入图片描述

实时动态同步配置(无需重启服务):spring cloud bus
第一步: 安装RabbitMQ
需要配合 RabbitMQ服务使用 ( RabbitMQ for Window 安装指南)

第二步:Config-server服务 添加 actuator 和 rabbit库

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-stream-binder-rabbit</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

第三步:Config-server 配置完成
添加 rabbit 配置和actutor 的 management 的路径解封。不然访问不到

server:
  port: 10000

spring:
  application:
    name: config-server
  cloud:
    config:
      server:
        git:
          uri: https://gitee.com/leonzhang2013/configuration-center.git
          default-label: master
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:8000/eureka

  rabbitmq:
    host: localhost
    port: 5672
    username: guest
    password: guest

management:
  endpoints:
    web:
      exposure:
        include: "*"

配置使用端 user-server
第一步:添加 pom

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-bus</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-stream-binder-rabbit</artifactId>
        </dependency>

第二步:添加rabbit 配置 applition.yml 中:
在这里插入图片描述
第三步:添加@RefreshScope 属性注解,表示该类,中的属性需要动态刷新(test.name)
在这里插入图片描述
测试:
启动 注册中心,config-server ,user-server 三个服务。
1、修改git 上的配置:例如 test.name =lisi 修改为 zhangsan
2、访问 user-servier 服务中的 测试链接 localhost:9091 查看数据,此时数据应该是 lisi
3、通过postman 访问 config-server 的刷新配置路径 http://localhost:10000/actuator/busrefresh
4、再次访问 localhost:9091 查看数据,此时数据应该是 zhangsan 测试结束。

关于第三步,老版本的是 bus-refresh 新版是 busrefresh
具体是那个可以访问:http://localhost:10000/actuator/mappings 去搜索一下 refresh 看看你的路径是那个。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1703866.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vulhub——Aria2、bash、catic

文章目录 一、Aria2 任意文件写入漏洞二、CVE-2014-6271&#xff08;Bash Shell 漏洞&#xff09;三、CVE-2022-46169&#xff08;Cacti 前台命令注入漏洞&#xff09; 一、Aria2 任意文件写入漏洞 Aria2是一个命令行下轻量级、多协议、多来源的下载工具&#xff08;支持 HTTP…

C# WPF入门学习主线篇(四)—— Button的常用属性

本期来详细介绍一下WPF中Button组件的属性都有哪些 一、准备阶段 首先&#xff0c;打开我们之前创建好的工程。 这是我们之前几期一起做过的工程&#xff0c;现在重新创建一个button&#xff0c;来熟悉一下他的属性。 选中创建的button&#xff0c;点击属性栏 二、接下来介绍…

基于Netty实现安全认证的WebSocket(wss)服务端

1.Netty服务端 服务端代码参考【基于Netty实现WebSocket服务端-CSDN博客】中的两种方式都可以&#xff1b;这里用的是第一种简单方式。 新增如下逻辑&#xff1a;添加SSLHandler SSLContext sslContext SslUtil.createSSLContext("JKS","D:\\workSpace\\day…

开源网页视频会议,WebRTC音视频功能比较

1. 概述 OpenAI 发布了新一代旗舰生成模型 GPT-4o,这是一款真正的多模态大模型,可以「实时对音频、视觉和文本进行推理」。 支持与 AI 实时语音对话,且响应时间达到毫秒级;交互中可识别人类情绪并以相应的情感做出回应;多语言能力的提升,WebRTC 成为大模型关键能力。 视频会议…

STL-list

目录 【本节目标】 1.list的介绍及使用 1.1 list的介绍&#xff08;双向链表&#xff09; 1.2 list的使用 1.2.1 list的构造 1.2.2 list iterator的使用&#xff08;迭代器&#xff09; 1.2.3 list capacity&#xff08;容量&#xff09; 1.2.4 list element access 1…

一键接入大模型:One-Api本地安装配置实操,POSTMAN、APIFOX调用CURL

前言 最近准备学习一下 Semantic Kernel, OpenAI 的 Api 申请麻烦,所以想通过 One-api 对接一下国内的在线大模型,先熟悉一下 Semantic Kernel 的基本用法,本篇文章重点记录一下OneApi安装配置的过程。 讯飞星火有 3.5 模型的 200w 个人免费 token,可以拿来学习。 讯飞星…

2.冒泡排序

样例输入 5 8 3 6 4 9 样例输出 3 4 6 8 9 以下是解题答案&#xff1a; class demo1{public static void main(String[] args) {Scanner scnnew Scanner(System.in);int[] array new int[scn.nextInt()];if(array.length>0&&array.length<200){for(int…

单点登录(JWT实现)

单点登陆的英文名是&#xff1a;Single Sign On&#xff08;简称SSO&#xff09;&#xff0c;只需要登陆一次&#xff0c;就可以访问所有信任的应用系统。 在单体项目中&#xff0c;我们登陆之后可以把验证用户信息的值放入session中&#xff0c;单个tomcat中的session是可以共…

MySQL 8窗口函数详解:高效数据处理的必备技能

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 MySQL 8窗口函数详解&#xff1a;高效数据处理的必备技能 前言窗口函数概述窗口函数的基本语法常用窗口函数类型窗口帧的定义与使用性能优化与注意事项 前言 你是否曾经遇到过需要对数据进行复杂统计…

软考高项 各章节知识点【细】

文章目录 前五章项目管理概论项目立项管理项目整合管理范围管理进度管理成本管理质量管理资源管理沟通管理风险管理采购管理干系人管理绩效域配置与变更管理招投标、政府采购 前五章 数字经济是继农业经济、工业经济之后的主要经济形态&#xff0c;是以数据资源为关键要素&…

ElementPlus 步骤条嵌套Popover 气泡卡片

业务场景&#xff1a;当前步骤条鼠标悬浮提示框&#xff0c;步骤条是for循环出来的 如下图: <el-steps finish-status"success"><el-popoverv-for"item in uniqueReverseArr"placement"top-start":title"item.title":width&…

“胖东来”超市商业模式,为何被誉为中国零售业是神一般的存在?

“胖东来”超市商业模式&#xff0c;为何被誉为中国零售业是神一般的存在&#xff1f; 文丨微三云营销总监胡佳东&#xff0c;点击上方“关注”&#xff0c;为你分享市场商业模式电商干货。 - 胖东来是中国商超界的天花板&#xff0c;被小米老板雷军&#xff1a;誉为“中国零…

img标签添加::before ::after 伪元素无效,伪元素增加:hover伪类无效

1 问题 img标签添加::before ::after 伪元素无效伪元素增加:hover伪类无效 2 解决 只能在img前后增加dom元素可以这样写:hover::before{} :hover::after{} 3 分析 3.1 定义 ::before 创建一个伪元素&#xff0c;其将成为匹配选中的元素的第一个子元素。常通过 content 属…

项目方案:社会视频资源整合接入汇聚系统解决方案(三)

目录 一、概述 1.1 应用背景 1.2 总体目标 1.3 设计原则 1.4 设计依据 1.5 术语解释 二、需求分析 2.1 政策分析 2.2 业务分析 2.3 系统需求 三、系统总体设计 3.1设计思路 3.2总体架构 3.3联网技术要求 四、视频整合及汇聚接入 4.1设计概述 4.2社会视频资源分…

Modbus协议基础

文章目录 Modbus概述Modbus TCP/IP Modbus概述 Modbus是由Modicon&#xff08;现为施耐德电气公司的一个品牌&#xff09;在1979年发明的&#xff0c;是全球第一个真正用于工业现场的应用层总线协议。 为更好地普及和推动Modbus在基于以太网上的分布式应用&#xff0c;目前施…

单细胞 10X 和seurat对象学习

单细胞seurat数据的基础知识 rm(list ls()) library(Seurat) #注意这个报错 #Warning: Feature names cannot have underscores (_), replacing with dashes (-) folderslist.files(./,pattern[123]$) folders scList lapply(folders,function(folder){ CreateSeuratObject(…

2024-5-14-从0到1手写配置中心Config之基于数据库的分布式锁

DistributedLocks实现 自动注入数据源。创建连接&#xff0c;保证不影响其他连接。locked原子变量判断是否加锁成功&#xff1b;Executor 定时任务&#xff0c;尝试获取锁。 init()初始化方法 使用注解PostConstruct初始化&#xff0c;使用数据源创建连接。 开启定时任务&am…

一个投稿好方法让你的文章早日发表

作为一名单位信息宣传员,我初入此行时,满腔热情,怀揣着传播单位价值、展示团队风采的理想,一头扎进了稿件撰写的海洋。我的目标很简单,就是通过文字的力量,让外界听到我们的声音,感受到我们的活力。然而,理想很丰满,现实却给我上了生动的一课。 起初,我遵循传统路径,选择了一家…

虚拟化知识学习

虚拟化知识学习 关键概念和术语的简要介绍 虚拟化的基本概念 虚拟机 (VM)&#xff1a;一个虚拟机是一个模拟计算机系统的环境。它运行在物理硬件之上&#xff0c;但与物理硬件隔离&#xff0c;提供类似于物理计算机的功能。 虚拟化技术&#xff1a;这是指使用软件来创建虚拟版…

如何去除视频上的文字?免费无痕去水印分享!视频制作良器!

对于需要进行二次创作的视频素材&#xff0c;去除原有的文字可以提供一个更加干净的画布&#xff0c;方便创作者在其基础上进行新的创作和编辑。同时&#xff0c;去除文字后的视频也更方便分享到各种平台&#xff0c;避免因为平台对文字的限制而导致视频无法发布或传播。 要去除…