springcloud进阶

Ribbon的简介与使用

  • 简介:Ribbon翻译过来是负载均衡的意思,即提供者provider可能存在集群多个服务器的情况,客户端Customer会帮助我们将请求进行分发到不同的服务器,假如有服务器A,B,现在有100个请求,客户端会根据服务器的个数进行分发,不会挤在某一台服务器上使服务宕机。默认使用的是轮询,可自己根据实际情况进行修改。

如果使用的是本地单机的情况下,将服务端的模块进行复制,模拟一个Ribbon使用场景。
注:复制的端口记得改对应的yml文件的端口,以及pom文件的artifactId,application.name 不需要改,做一个服务集群。

客户端调用服务端自动启用轮询分发的模式。

  • 如果需要调整ribbon的模式,请到消费者Customer端进行修改对应的参数即可(yml/properties)。

      dm-user-provider: # 需要对哪个服务做调整
        ribbon: # 调整什么内容,这里调整的是ribbon
          NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # NFLoadBalancerRuleClassName这是固定的格式,然后指定你要使用的类全路径.(包名+类名),不太清楚的小伙伴可以到https://github.com/Netflix/ribbon/tree/master/ribbon-loadbalancer/src/main/java/com/netflix/loadbalancer进行了解。
    

Zuul网关

  • 简介:Zuul网关主要是帮助我们做Route路由工作。给前端一个固定的格式进行传递,来调用后端的接口。

  • 使用时,请先引入pom依赖。

      <parent>
      	<groupId>org.springframework.boot</groupId>
      	<artifactId>spring-boot-starter-parent</artifactId>
      	<!--这里的1.5.6.RELEASE是降版之后的版本,如果你需要最新的版本请使用脚手架或者自行到网上查阅-->
      	<version>1.5.6.RELEASE</version>
      	<relativePath/> <!-- lookup parent from repository -->
      </parent>
      	<groupId>com.springcloud.gateway.zuul</groupId>
      	<artifactId>dm-gateway-zuul</artifactId>
      	<version>0.0.1-SNAPSHOT</version>
      	<name>dm-gateway-zuul</name>
      	<description>Demo project for Spring Cloud</description>
      
      	<properties>
      		<java.version>1.8</java.version>
      		<!--这里的Dalston.SR4是降版之后的版本,如果你需要最新的版本请使用脚手架或者自行到网上查阅-->
      		<spring-cloud.version>Dalston.SR4</spring-cloud.version>
      	</properties>
      
      	<dependencies>
      		<!--spring-cloud-starter-eureka和spring-cloud-starter-zuul是降版之后的版本,如果你需要最新的版本请使用脚手架或者自行到网上查阅-->
      		<dependency>
      			<groupId>org.springframework.cloud</groupId>
      			<artifactId>spring-cloud-starter-eureka</artifactId>
      		</dependency>
      		<dependency>
      			<groupId>org.springframework.cloud</groupId>
      			<artifactId>spring-cloud-starter-zuul</artifactId>
      		</dependency>
      
      		<dependency>
      			<groupId>org.springframework.boot</groupId>
      			<artifactId>spring-boot-starter-test</artifactId>
      			<scope>test</scope>
      		</dependency>
      	</dependencies>
      
      	<dependencyManagement>
      		<dependencies>
      			<dependency>
      				<groupId>org.springframework.cloud</groupId>
      				<artifactId>spring-cloud-dependencies</artifactId>
      				<version>${spring-cloud.version}</version>
      				<type>pom</type>
      				<scope>import</scope>
      			</dependency>
      		</dependencies>
      	</dependencyManagement>
      
      	<build>
      		<plugins>
      			<plugin>
      				<groupId>org.springframework.boot</groupId>
      				<artifactId>spring-boot-maven-plugin</artifactId>
      			</plugin>
      		</plugins>
      	</build>
    
  • 对启动类上加入注解

      @SpringBootApplication
      @EnableZuulProxy
      @EnableDiscoveryClient
      public class DmGatewayZuulApplication {
      
      	public static void main(String[] args) {
      		SpringApplication.run(DmGatewayZuulApplication.class, args);
      	}
      
      }
    
  • yaml文件的编写:

      server:
        port: 8083
      eureka:
        client:
          fetch-registry: true
          register-with-eureka: true
          service-url:
            defaultZone: http://admin:123456@localhost:7776/eureka
      zuul:
        routes: # 开启zuul的路由功能
          dm-user-consumer: /user/** # dm-user-consumer是将拦截路径分发到什么服务上, /user/**是你要拦截的路径
        SecondFilter: # 过滤器名称,对哪个过滤器进行操作
          pre: # 过滤器类型,pre,route,post,error类型
            disable: true # 是否禁用,是否对该过滤器进行禁用。
    
  • 过滤器流程图:

在这里插入图片描述

编写过滤器

@Component//将该过滤器添加到Spring组件中,否则不生效
//组件名称任意,需要继承自ZuulFilter并重写其中的四个方法
public class PreFilter extends ZuulFilter{

   
   //此过滤器的类型,是pre/route/post/error
    @Override
    public String filterType() {
        return FilterConstants.PRE_TYPE;
    }

	//过滤器执行顺序,数值越小优先级别越高
    @Override
    public int filterOrder() {
        return 0;
    }

	//是否执行
    @Override
    public boolean shouldFilter() {
        return true;
    }

//真正执行的方法体
    @Override
    public Object run() {
    	//获取上下文对象
        RequestContext ctx = RequestContext.getCurrentContext();
        //通过上下文获取request对象
        HttpServletRequest request = ctx.getRequest();
        	//从header中获取参数
            String token = request.getHeader("token");
            if (token == null || "".equals(token)) {
                ctx.setSendZuulResponse(false);//执行完此过滤器之后,后面的过滤器设置为不生效
                ctx.setResponseStatusCode(401);//返回的状态码
                ctx.setResponseBody("{\"msg\":\"401 PreFilter if fail ! Please try again!\"}");//返回body体
                return "try again!";//返回的信息暂时没有任何意义
            }
        return "pass";//返回的信息暂时没有任何意义
    }
  • 多过滤器

      @Component
      public class PreFilter extends ZuulFilter{
    
          @Override
          public String filterType() {
              return FilterConstants.PRE_TYPE;
          }
      
          @Override
          public int filterOrder() {
              return 0;
          }
      
          @Override
          public boolean shouldFilter() {
              return true;
          }
      
          @Override
          public Object run() {
          	//获取上下文对象
              RequestContext ctx = RequestContext.getCurrentContext();
              //通过上下文获取request对象
              HttpServletRequest request = ctx.getRequest();
              //从request对象中获取参数
              String key = request.getParameter("key");
              System.out.println("1 access filter!");
              //通过上下文对象给应用中某属性设置参数
              ctx.set("thirdFilter",true);
              if("1".equals(key)){
                  ctx.setSendZuulResponse(false);//执行完此过滤器之后,后面的过滤器设置为不生效
                  ctx.setResponseStatusCode(-401);
                  ctx.setResponseBody("{\"msg\":\"key"+ key +" is end,and set  ZuulResponse is false!\"}");//返回的状态码
                  ctx.set("thirdFilter",false);//返回body体
              }
              return "pass";//返回的信息暂时没有任何意义
          }
      }
    

过滤器二:

@Component
public class SecondFilter extends ZuulFilter {
    @Override
    public String filterType() {
        return FilterConstants.PRE_TYPE;
    }

    @Override
    public int filterOrder() {
        return 1;
    }

    @Override
    public boolean shouldFilter() {
    	//获取上下文对象,判断此过滤器是否生效/执行
        RequestContext ctx = RequestContext.getCurrentContext();
        return ctx.sendZuulResponse();
    }

    @Override
    public Object run() {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        String key = request.getParameter("key");
        System.out.println("2 access filter!");
        if("2".equals(key)){
            ctx.setSendZuulResponse(false);
            ctx.setResponseStatusCode(-401);
            ctx.setResponseBody("{\"msg\":\"key"+ key +" is end,and set  ZuulResponse is false!\"}");
        }
        return "pass";
    }

过滤器三:

@Component
public class ThirdFilter extends ZuulFilter {
    @Override
    public String filterType() {
        return FilterConstants.PRE_TYPE;
    }

    @Override
    public int filterOrder() {
        return 2;
    }

    @Override
    public boolean shouldFilter() {
    //获取上下文对象,判断此过滤器是否生效/执行,并判断存放的对象是否为真,两个条件都满足,就执行该过滤器
        RequestContext ctx = RequestContext.getCurrentContext();
        return ctx.sendZuulResponse() && (Boolean)ctx.get("thirdFilter");
    }

    @Override
    public Object run() {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        String key = request.getParameter("key");
        System.out.println("3 access filter!");
        if("3".equals(key)){
            ctx.setSendZuulResponse(false);
            ctx.setResponseStatusCode(-401);
            ctx.setResponseBody("{\"msg\":\"key"+ key +" is end,and set  ZuulResponse is false!\"}");
        }
        return "pass";
    }

Config

  • 简介:没有Config之前我们是每个模块进行单独配置,有了Config之后,将我的配置信息统一的放入git上进行托管,我们直接拉去git上面的配置即可。

  • 1、在GitHub上创建一个仓库,这里使用的是码云GitHub,仓库名称为dm-config-demo,根据自己的实际情况建立分支语句,这里使用到的分支有两个,他们分别是mater分支springcloud分支,他们底下分别于一个文件夹,是config-file,文件夹中有一个文件,是dm-gateway-zuul-dev.properties,里面的内容就是一个token属性。

在这里插入图片描述

  • 2、导入pom文件

    org.springframework.boot spring-boot-starter-parent 1.5.6.RELEASE com.springcloud.config dm-config-zuul 0.0.1-SNAPSHOT dm-config-zuul Demo project for Spring Cloud
      <properties>
      	<java.version>1.8</java.version>
      	<!--降版-->
      	<spring-cloud.version>Dalston.SR4</spring-cloud.version>
      </properties>
    
      <dependencies>
      	<dependency>
      		<groupId>org.springframework.cloud</groupId>
      		<artifactId>spring-cloud-config-server</artifactId>
      	</dependency>
    
      	<dependency>
      		<groupId>org.springframework.boot</groupId>
      		<artifactId>spring-boot-starter-test</artifactId>
      		<scope>test</scope>
      	</dependency>
      	<dependency>
      		<groupId>org.springframework.cloud</groupId>
      		<artifactId>spring-cloud-starter-eureka</artifactId>
      	</dependency>
      </dependencies>
    
      <dependencyManagement>
      	<dependencies>
      		<dependency>
      			<groupId>org.springframework.cloud</groupId>
      			<artifactId>spring-cloud-dependencies</artifactId>
      			<version>${spring-cloud.version}</version>
      			<type>pom</type>
      			<scope>import</scope>
      		</dependency>
      	</dependencies>
      </dependencyManagement>
    
      <build>
      	<plugins>
      		<plugin>
      			<groupId>org.springframework.boot</groupId>
      			<artifactId>spring-boot-maven-plugin</artifactId>
      		</plugin>
      	</plugins>
      </build>		
    
  • 3、修改主启动类

      @SpringBootApplication
      @EnableDiscoveryClient
      @EnableConfigServer//启用Config服务器
      public class DmConfigZuulApplication {
      
      	public static void main(String[] args) {
      		SpringApplication.run(DmConfigZuulApplication.class, args);
      	}
      
      }	
    
  • 4、yml文件

      server:
        port: 8084
      eureka:
        client:
          fetch-registry: true
          register-with-eureka: true
          service-url:
            defaultZone: http://admin:123456@localhost:7776/eureka
      spring:
        application:
          name: dm-config-zuul
        cloud:
          config:
            server: # ConfigServer相关配置
              git:
                uri: https://gitee.com/yuhaiSteven/dm-config-demo.git # 你创建的项目路径
                username: yuhaiSteven # gitConfig项目的用户名
                password: yuhai980522. # gitConfig项目的密码
                search-paths: config-file # 重要配置在什么文件夹下面
    

启动ConfigServer服务器,并启动我们的Postman工具,通过get请求进行访问:
localhost:8084/dm-gateway-zuul/dev/springcloud
localhost:8084是我们的config所在工程/服务器;
dm-gateway-zuul 是我们需要读取的配置文件
dev是我们配置文件的版本,dev一般是开发,test是测试,pro/prod是生产;
springcloud是我们需要使用的分支;

Config Customer端,这里使用的是Zuul网关

  • application.yml是运行时执行的文件,bootstrap.yml是运行在此文件之前;

  • 创建一个bootstrap.yml;

      spring:
        application:
          name: dm-gateway-zuul # 将服务名称提前到此文件中
        cloud:
          config:
            uri: http://localhost:8084 # configClient读取的ConfigServer地址
            profile: dev # 读取的是什么版本
            label: master # 读取的是什么分支
            # 读取的格式是 uri的地址/文件名称/读取版本/分支
    

配置Config中的配置手动刷新

  • 1、在Config Client中导入手动刷新的依赖:

      <dependency>
      		<groupId>org.springframework.boot</groupId>
      		<artifactId>spring-boot-starter-actuator</artifactId>
      	</dependency>
    
  • 2、在Zuul对应的过滤器上加上注解:

      @RefreshScope
    
  • 3、在此过滤器上要给什么属性读取什么样的配置:

       @Value("${token}")
       private Boolean token;
    
  • 例如:

      	@Component
      @RefreshScope
      public class PreFilter extends ZuulFilter{
      
          @Value("${token}")
          private Boolean token;
          @Override
          public String filterType() {
              return FilterConstants.PRE_TYPE;
          }
      
          @Override
          public int filterOrder() {
              return 0;
          }
      
          @Override
          public boolean shouldFilter() {
              return true;
          }
      
          @Override
          public Object run() {
              RequestContext ctx = RequestContext.getCurrentContext();
              HttpServletRequest request = ctx.getRequest();
              String key = request.getParameter("key");
              /*System.out.println("1 access filter!");
              ctx.set("thirdFilter",true);
              if("1".equals(key)){
                  ctx.setSendZuulResponse(false);
                  ctx.setResponseStatusCode(-401);
                  ctx.setResponseBody("{\"msg\":\"key"+ key +" is end,and set  ZuulResponse is false!\"}");
                  ctx.set("thirdFilter",false);
              }*/
              if(token) {
                  String token = request.getHeader("token");
                  if (token == null || "".equals(token)) {
                      ctx.setSendZuulResponse(false);
                      ctx.setResponseStatusCode(401);
                      ctx.setResponseBody("{\"msg\":\"401 PreFilter if fail ! Please try again!\"}");
                      return "try again!";
                  }
              }
              return "pass";
          }
      }
    
  • 启动服务,在postman中进行操作:

      http://localhost:8083/refresh  
      # http://localhost:8083是此服务名称,refresh是刷新
    

在这里插入图片描述
如果是出现这张图所示的内容,已更新到内容,如果是[]空括号,就没有更新到内容。

加密解密

  • 因为jre版本对加密解密的内容有长度限制,需要将在这里插入图片描述
    两个jar文件拷贝到你电脑上的jdk/jre目录的security目录下,拷贝到任意一个即可。
    我本地的电脑jdk拷贝目录应该是’D:\Program Files\Java\jdk1.8.0_131\jre\lib\security’,
    jre拷贝目录应该是’D:\Program Files\Java\jre1.8.0_131\lib\security’,即可。

  • 在Config Server端建立bootstrap.yaml文件:

      encrypt:
      	 key: dm # 相当于开启加密解密功能,dm是项目的通用前缀
    
  • 使用postman工具进行加密解密:

      http://localhost:8084/encrypt  # http://localhost:8084/是我本地的ConfigServer地址
      http://localhost:8084/decrypt # encrypt是加密,decrypt是解密
      使用的请求方式是post
      ![在这里插入图片描述](https://img-blog.csdnimg.cn/20190724183833504.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80Mjc3OTU2MA==,size_16,color_FFFFFF,t_70)
    

    然后点击body --> raw,输入对应的加解密内容,开始加解密,加解密成功的内容显示在下方Body中。

git中的核心Config配置

  • 如果你对加密的内容进行解密。比如,我对true进行加密,加密后的文本是d75a7e932ea7c2e6bad0bcd9d7a8dba91da99876fa37f7646b05de0e4a162c49
    那么我书写到properties文件中应该是token = {cipher}d75a7e932ea7c2e6bad0bcd9d7a8dba91da99876fa37f7646b05de0e4a162c49,其中{cipher}代表的是这是加密的内容,需要解密,其后面的内容是我已经对true进行加密的内容。
  • 如果是yml文件,需要对=号后面的内容用单引号括起来,否则会出现解析错误。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值