新版本springcloud(一)

15 篇文章 0 订阅

新版本的微服务,他的springboot版本是在2.x以上,springcloud在H以上 在新版本上,使用eureka

开始

首先我们使用微服务的话,需要一个父工程,父工程不需要什么东西,但需要一个pom.xml文件来聚合这些依赖

添加或者修改他
<packaging>pom</packaging>
然后<properties>来定义依赖的版本
<dependencyManagement> 里面包含的依赖是可以被子项目给依赖的,如果子项目直接<artifactId>引入则使用的是父工程的,如果把坐标的信息写的完整且有版本号,则子项目使用的是自己的依赖

本次使用的坐标 父工程
 <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <junit.version>4.12</junit.version>
        <log4j.version>1.2.17</log4j.version>
        <lombok.version>1.16.18</lombok.version>
        <mysql.version>5.1.47</mysql.version>
        <druid.version>1.1.16</druid.version>
        <mybatis.spring.boot.version>1.3.0</mybatis.spring.boot.version>
    </properties>
    <dependencyManagement>
        <dependencies>
            <!--spring boot 2.2.2-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>2.2.2.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!--spring cloud Hoxton.SR1-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Hoxton.SR1</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!--spring cloud alibaba 2.1.0.RELEASE-->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>·</artifactId>
                <version>2.1.0.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>${mysql.version}</version>
            </dependency>
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid</artifactId>
                <version>${druid.version}</version>
            </dependency>
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>${mybatis.spring.boot.version}</version>
            </dependency>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>${junit.version}</version>
            </dependency>
            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>${log4j.version}</version>
            </dependency>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>${lombok.version}</version>
                <optional>true</optional>
            </dependency>
        </dependencies>
    </dependencyManagement>

Eureka

坐标跟换
客户端
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>


服务端
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>

其他的跟老版本的一样,但是eureka已经停止更新了,我们需要找一个可以替代他的产品,如zookeeper和consul

zookeeper

安装zookeeper
坐标
      <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-zookeeper-discovery</artifactId>
        </dependency>

注意,出现了那安装的zookeeper和maven的版本不一致的会报错,所以我们可以吧zookeeper给剔除

      <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-zookeeper-discovery</artifactId>
            <exclusions>
                <exclusion>
                         <groupId>org.apache.zookeeper</groupId>
                         <artifactId>zookeeper</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <version>3.4.14</version>  <!--引入和安装的zookeeper相同的版本-->
        </dependency>

yml
------------------
spring:
  application:
    name: 服务名称
  cloud:
    zookeeper:
      connect-string: 127.0.0.1:2181   #zookeeper的地址,2181默认端口

在启动类添加注解,@EnableDiscoveryClient

Consul

作用

服务发现:提供http和dns两种发现方式

健康监测:支持多种协议,http,tcp,docker,shell脚本定制 kv存储:key,value的存储方式 多数据中心:支持多数据中心 可视化web界面

使用

下载
https://www.consul.io/downloads


安装

使用
https://www.springcloud.cc/spring-cloud-consul.html


启动后可以访问8500端口可以查看服务


新建子工程
添加坐标
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-consul-discovery</artifactId>
        </dependency>
其他基础坐标就不说了


yml
-------------------
spring:
  application:
    name: 服务名称
  cloud:
    consul:
      host: localhost
      port: 8500
      discovery:
        service-name: ${spring.application.name}

默认端口就是8500


启动类依然加上@EnableDiscoveryClient注解


我们的服务提供者和消费者都是同样的配置


三个注册中心的区别

cap
c:Consistency强一致性
a:Availability 可用性
p:partition tolerance 分区容错性

该理论关注的粒度是数据,不是设计的策略

ap eureka
cp zookeeper/consul

补充:

注意,当使用ribbon时自定义策略时,那么该配置不能再@ComponentScan所扫描的包下及其子包

替换策略时还可以这样
在主启动类上加
@RibbonClient(name = "服务名称",configuration = MySelfRule.class)

MySelfRule是负载均衡策略

openFeign

openFeign是一个声明式的webService客户端,是定义一个服务接口然后在上面添加注解,
支持springmvc标准注解,


使用
--------------
坐标
---------------------
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        里面整合了ribbon,hystrix

启动类
--------------
@EnableFeignClients


yml
----------------------
openfigen默认等一秒,过后就超时

#设置feign客户端超时时间(OpenFeign默认支持ribbon)
ribbon:
  #指的是建立连接所用的时间,适用于网络状况正常的情况下, 两端连接所用的时间
  ReadTimeout: 5000
  #指的是建立连接后从服务器读取到可用资源所用的时间
  ConnectTimeout: 5000



接口
----------
@Component
@FeignClient(value = "服务名称")
public interface PaymentFeignService {
    @GetMapping(value = "/payment/get/{id}")
    CommonResult<Payment> getPaymentById(@PathVariable("id") Long id);

    @GetMapping(value = "/payment/feign/timeout")
    String paymentFeignTimeout();
}

日志


openfigen提供了日志打印功能,对openfeign的接口调用情况进行监控输出
日志级别:
NONE :默认,不显示任何日志
BASIC:仅记录请求方法,url,响应状态码及执行时间
HEADERS:除了BASIC中定义的信息之外,还有请求响应的头信息
FULL:除了HEADRES中定义信息外,还有请求响应的正文及元数据



配置
@Configuration
public class FeignConfig {

    @Bean
    Logger.Level feignLoggerLevel(){
        return Logger.Level.FULL;
    }
}


yml需要开启日志的feign客户端
logging:
  level:
    com.atguigu.springcloud.service.PaymentFeignService: debug

gateway新一代网关

注意是springboot2.x版本使用的
作用
-----------------
反向代理
鉴权
流量控制
熔断
日志监控

特性
--------------
动态路由,能够匹配任何请求
可以对路由指定Predicate(断言)Filter(过滤器)
集成Hystrix的断路器功能
集成cloud的服务发现功能
支持路径重写,
请求限流功能

与zuul.x的区别
zuul是一个基于阻塞i/o的api gateway   gateway不阻塞

gateway模型 spring webflux是一个非阻塞的响应式框架

核心

1.路由 路由是构建网关的基本模块,由id,目标uri,一系列的断言和过滤器组成,断言为!true则匹配该路由, 2.断言 如果请求与断言相匹配则进行路由 3.过滤 使用过滤器,可以在请求被路由前或者之后队请求进行修改
新建工程

基础坐标这里就不说了

加入网关
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>


yml
--------------------------
spring:
  application:
    name: 服务名称
  cloud:
    gateway:
      discovery:
        locator:
          enabled: false #开启从注册中心动态创建路由的功能,利用微服务名进行路由
      routes:
        - id: payment_routh #路由的ID,没有固定规则但要求唯一,建议配合服务名
          uri: http://localhost:8001   #匹配后提供服务的路由地址
          predicates:
            - Path=/payment/get/**   #断言,路径相匹配的进行路由

        - id: payment_routh2
          uri: http://localhost:8001
          predicates:
            - Path=/payment/lb/**   #断言,路径相匹配的进行路由

访问
localhost:9527/payment/get/1   由于上面我们配置了这个断言,
所以该请求会被路由到http://localhost:8001服务上的/payment/get/1 接口上


或者换成这个
uri:lb://cloud-payment-service  指定服务名称  ,不写端口和ip


注意:lb表示启用负载均衡的功能

路由的第二种配置方式

创建RouteLocator的bena

@Configuration
public class GateWayConfig {
    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder routeLocatorBuilder) {
        RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes();
        routes.route("path_route_atguigu", r -> r.path("/payment/get/**").uri("lb://cloud-payment-service"))
                .build();
        return routes.build();
    }
}


这样子路由也是可以的

Route Predicate Factories

Gateway内置了多种路由谓词工厂,用来匹配http请求。当多个一起使用时,是and的关系,即需要所有的谓词工厂都匹配,才匹配这个路由
1.After
  表示当前请求在指定时间之后才匹配
  datetime 数据类型是 ZonedDateTime,带有时区

使用
         predicates:
            - After=2020-11-01T11:05:08.020+08:00[Asia/Shanghai]


2.Before
  则和上面的相反,表示当前请求在指定时间之前才匹配
   predicates:
     - Before=2020-11-01T11:05:08.020+08:00[Asia/Shanghai]

3.Between
   当前请求在指定时间中间才匹配,并且date1要小于date2
   predicates:
     - Between=2020-11-01T11:08:08.020+08:00[Asia/Shanghai],2020-11-01T11:15:08.020+08:00[Asia/Shanghai]


4.Cookie
  当前请求中的cookie值匹配配置的cookie参数值时生效
   
   predicates:
            - Cookie=token,tokenvalue\d+

    token  是请求cookie中的参数的名字
    tokenvalue是 请求cookie中的参数的值,配置的值是Java中的正则表达式形式。
    d+表示后面可以加数字,仅数字

5.Header
  当前请求中的header值匹配配置的header参数值时生效
   
   predicates:
            - Header=X-Token-Id,\d+
        表示请求头中必须存在X-Token-Id且它的值必须是数字

6.Host
  匹配请求头中的Host的值
  predicates:
            - Host=**.gateway.com,{study}.baidu.com
    
   **.gateway.com 表示请求中的Host的值需要配置这种ant风格
    
   {study}.baidu.com  study这个模版变量可以在GatewayFilter中获取到
   ServerWebExchange.getAttributes().get(ServerWebExchangeUtils.URI_TEMPLATE_VARIABLES_ATTRIBUTE)获取


7.Method
  匹配请求头中的Method的值,methods 需要匹配的方法,比如GET、POST等
  
  predicates:
      - Method=GET,POST,PUT # 只有get,post,put请求才能匹配上方这个路由

8.Path
  匹配请求路径。
    predicates:
            - Path=/product/findOne/{productId},/product//**
           支持uri模版变量
         productId可以在GatewayFilter中获取
    
    Map<String, String> uriVariables =   ServerWebExchangeUtils.getPathPredicateVariables(exchange);
String segment = uriVariables.get("productId");


9.Query
  匹配请求参数
  
  predicates:
            #- Query=pwd
            - Query=username,\d+
    
   Query=pwd 表示请求中必须存在 pwd这个请求参数
   Query=username,\d+ 表示请求中必须存在username这个参数,且它的值必须是数字


10.RemoteAddr
   匹配请求的ip地址,支持ipv4和ipv6。
     
     predicates:
            - RemoteAddr=127.0.0.1/16
     
     sources 地址列表eg:127.0.0.1/16 后方的/16是子网掩码

11.Weight
   根据权重来分发请求,权重是根据group来计算的。
   - id: product-provider
          uri: https://weighthigh.org
          predicates:
            - Weight=group1,6
        - id: user-consumer
          uri: https://weightlow.org
          predicates:
            - Weight=group1,4
      group 组,权重根据组来计算
      weight 权重值,是一个 Int 的值

   60%的请求会落在product-provider, 40%的请求会落在user-consumer

自定义route predicate factory

编写一个类,实现RoutePredicateFactory接口,
或继承AbstractRoutePredicateFactory1.AbstractRoutePredicateFactory 中的 C 表示 配置文件类。
2.重写shortcutFieldOrder此方法,表示的配置文件中参数的位置
3.重写apply(C c)方法,表示的是具体的业务逻辑

我们自己编写的类必须要以RoutePredicateFactory结尾



@Slf4j
@Component
public class TokenRoutePredicateFactory extends AbstractRoutePredicateFactory<TokenRoutePredicateFactory.Config> {

    public TokenRoutePredicateFactory() {
        super(Config.class);
    }

    @Override
    public List<String> shortcutFieldOrder() {
        return Lists.newArrayList("gww");
    }

    @Override
    public Predicate<ServerWebExchange> apply(Config config) {
        return exchange -> {
            log.info("判断请求头中是否存在gww这个参数");
            String gww = exchange.getRequest().getQueryParams().getFirst(config.getGww());
            return StringUtils.isNotBlank(gww);
        };
    }

    @Data
    public static class Config {
        private String gww;
    }
}


使用

------------------
predicates:
     - gww=gww

路由过滤器

gateway内置了多种过滤器,他们都由gatewayfilter的工厂类来产生
1.AddRequestHeader 过滤器工厂
   通过名称我们可以快速明白这个过滤器工厂的作用是添加请求头。
   符合规则匹配成功的请求,将添加 X-Request-Foo:bar 请求头,将其传递到后端服务中,后方服务可以直接获取请求头信息
    
spring:
  cloud:
    gateway:
      routes:
        - id: add_request_header_route
  uri: http://c.biancheng.net
  filters:
    - AddRequestHeader=X-Request-Foo, Bar

2.RemoveRequestHeader 过滤器工厂
  RemoveRequestHeader 是移除请求头的过滤器工厂,可以在请求转发到后端服务之前进行 Header 的移除操作。
  
spring:
  cloud:
    gateway:
      routes:
  - id: removerequestheader_route
  uri: http://c.biancheng.net
    - RemoveRequestHeader=X-Request-Foo

3.SetStatus 过滤器工厂
  SetStatus 过滤器工厂接收单个状态,用于设置 Http 请求的响应码
   
spring:
  cloud:
    gateway:
      routes:
        - id: setstatusint_route
  uri: http://c.biancheng.net
  filters:
    - SetStatus=401


4.RedirectTo过滤器工厂
  RedirectTo 过滤器工厂用于重定向操作,比如我们需要重定向到百度。
   
spring:
  cloud:
    gateway:
      routes:
        - id: prefixpath_route
  uri: http://c.biancheng.net
  filters:
    - RedirectTo=302, http://baidu.com

自定义Spring Cloud Gateway过滤器工厂

需要继承 AbstractGatewayFilterFactory 类,重写 apply 方法的逻辑,命名需要以 GatewayFilterFactory 结尾
@Component
public class CheckAuth2GatewayFilterFactory
        extends AbstractGatewayFilterFactory<CheckAuth2GatewayFilterFactory.Config> {

    public CheckAuth2GatewayFilterFactory() {
        super(Config.class);
    }

    @Override
    public GatewayFilter apply(Config config) {
    return (exchange, chain) -> {
      System.err.println("进入了CheckAuth2GatewayFilterFactory" + config.getName());
      ServerHttpRequest request = exchange.getRequest().mutate()
      .build();
      return
      chain.filter(exchange.mutate().request(request).build());
    }
  }

    public static class Config {
        private String name;

        public void setName(String name) {
            this.name = name;
        }

        public String getName() {
            return name;
        }
    }
}


使用如下:
filters:
  - name: CheckAuth2
  args:
    name: 张三

如果你的配置是 KeyValue 这种形式的,那么可以不用自己定义配置类,直接继承 AbstractNameValueGatewayFilterFactory 类即可。

AbstractNameValueGatewayFilterFactory 类继承了 AbstractGatewayFilterFactory,定义了一个 NameValueConfig 配置类,NameValueConfig 中有 name 和 value 两个字段。




继承 AbstractNameValueGatewayFilterFactory 方式定义过滤器工厂
@Component
public class CheckAuthGatewayFilterFactory extends AbstractNameValueGatewayFilter-actory {

    @Override
    public GatewayFilter apply(NameValueConfig config) {
        return (exchange, chain) -> {
            System.err.println("进入了CheckAuthGatewayFilterFactory" + config.getName() + "\t" + config.getValue());
            ServerHttpRequest request = exchange.getRequest().mutate().build();

            return chain.filter(exchange.mutate().request(request).build());
        };
    }
}


使用:
filters:
    - CheckAuth=zhangsan,
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值