Springboot + SpringCloud + Nacos + OpenFeign + Gateway

Springboot + SpringCloud + Nacos + OpenFeign + Gateway

根节点相关依赖


    org.springframework.boot
    spring-boot-starter-parent
    2.7.8
     


    com.alibaba.cloud
    spring-cloud-alibaba-dependencies
    2021.0.4.0
    pom
    import


    org.springframework.cloud
    spring-cloud-dependencies
    2021.0.5
    pom
    import
  1. Nacos下载和安装

官网:https://nacos.io/zh-cn/

从GitHub下载对应版本nacos,版本对应关系:

https://github.com/alibaba/spring-cloud-alibaba/wiki/%E7%89%88%E6%9C%AC%E8%AF%B4%E6%98%8E

cmd进入nacos/bin/目录

windows启动指令(单机模式):

startup.cmd -m standalone

以集群模式启动:

startup.cmd

停止运行:

shutdown.cmd

默认端口(集群需要复制多个安装包并修改端口,按实际情况修改):修改文件/conf/application.properties

server.port=8848

访问http://localhost:8848/nacos/index.html 进入服务中心管理页面,用户名和密码默认都为nacos,此时服务列表为空

  1. 服务发现(2021.0.4.0)

依赖:


    org.springframework.boot
    spring-boot-starter


    com.alibaba.cloud
    spring-cloud-starter-alibaba-nacos-discovery

在yml配置文件中配置服务中心地址和服务名称(必须),指定该服务端口号

spring:
  cloud:
    nacos:
      #服务中心
      server-addr: localhost:8848
      #discovery:
        #集群名称
        #cluster-name: USER
        #命名空间 相同命名空间可以互相访问
        #namespace: 156727b1-1778-482b-8c20-0321151d660b
        #ephemeral: false
  application:
    name: user-service
server:
  port: 8002

成功启动项目后,管理台会看到该服务已注册到服务列表

指定命名空间后,不同命名空间的服务不能相互访问.

集群指定后,相当于分组,可以相互访问

  1. 服务间通信OpenFeign

服务间利用http请求进行通信,可以使用RestTemplate和OpenFeign

OpenFeign比RestTemplate有一定优势

OpenFeign依赖(3.1.5):


    org.springframework.cloud
    spring-cloud-starter-openfeign

yml配置:

启动类添加启动Feign注解:

@EnableFeignClients

使用:"user-service"为目的目标服务名称,

@FeignClient("user-service")
public interface UserClient {
    @RequestMapping("/user/{id}")
    public String getUserById(@PathVariable("id") Long id);
}

注入到controller中

@Autowired
UserClient userClient;
String userById = userClient.getUserById(userId);

feign优化配置(默认使用Urlconnection,无连接池)

日志级别尽量用basic

使用 HttpClient 或 OKHttp 代替 URLConnection

日志打印使用基本配置,使用httpclient或者okhttp,启用连接池

导入httpclient依赖(11.10)



    io.github.openfeign
    feign-httpclient
feign:
  httpclient:
    enabled: true
    max-connections: 200
    max-connections-per-route: 50
  client:
    config:
      default:
        logger-level: basic

也可以在配置类中指定:

@Bean
public Logger.Level logLevel(){
    return Logger.Level.BASIC;
}

配置(客户端-service-service)负载均衡策略

导入依赖(高版本已移除ribbon)


    org.springframework.cloud
    spring-cloud-starter-loadbalancer

创建配置文件

@Configuration
@LoadBalancerClients(defaultConfiguration = {NacosConfig.class})
public class NacosConfig {
    //2021版本已剔除ribbon
    /**
     * 配置客户端侧负载均衡规则 service-service
     */
    @Bean
    public ReactorLoadBalancer specLoadBalancer(Environment environment, LoadBalancerClientFactory loadBalancerClientFactory) {
        String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
        return new RoundRobinLoadBalancer(loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name);
    }
}
  1. 网关(单独服务)

网关也作为一个微服务需要注册到注册中心,纳入管理,实际项目中可以布置多套网关

依赖:


    org.springframework.boot
    spring-boot-starter


    org.springframework.cloud
    spring-cloud-starter-gateway


    com.alibaba.cloud
    spring-cloud-starter-alibaba-nacos-discovery


    org.springframework.cloud
    spring-cloud-starter-loadbalancer

配置端口和服务名称(必须),配置路由和跨域问题相关

server:
  port: 9000
spring:
  cloud:
    nacos:
      server-addr: localhost:8848
    gateway:
      routes:
        - id: user-service
          uri: lb://user-service
          predicates:
            - name: Path
              args:
                name: Path
                value: /user/**
        - id: order-service
          uri: lb://order-service
          predicates:
            - name: Path
              args:
                name: Path
                value: /order/**
      globalcors:
        # 跨域问题处理
        cors-configurations:
          '[/**]':
            #本次跨域检测有效期毫秒
            maxAge: 36000
            #是否允许携带cookie
            allowCredentials: true
            #允许请求携带的头信息
            allowed-headers:
              - "*"
            #允许哪些网站的跨域请求
            allowed-origins:
              - "http://localhost:8080"
            #允许的ajax请求方式
            allowed-methods:
              - "GET"
              - "POST"
              - "PUT"
              - "DELETE"
              - "OPTIONS"
        #解决options请求被拦截问题
        add-to-simple-url-handler-mapping: true
  application:
    name: gateway-service

路由配置或者为

    gateway:
      routes:
        - id: user-service
          uri: lb://user-service
          predicates:
            - Path=/user/**
        - id: order-service
          uri: lb://order-service
          predicates:
            - Path=/order/**

-----------------------

断言工厂相关说明(简写方式)

predicates:
- Path=/provider/hello/**      #断言:路径相匹配进行路由
- Before=2021-08-25T12:53:46.101+08:00[Asia/Shanghai] #匹配这个时间之前的请求
- After=2021-08-25T12:53:46.101+08:00[Asia/Shanghai]  #匹配这个时间之后的请求
- Between=2021-08-25T12:53:46.101+08:00[Asia/Shanghai],2021-09-25T12:53:46.101+08:00[Asia/Shanghai] #匹配这个两个时间的请求
- Cookie=username,zzyy
- Header=X-Request-Id,\d+  #请求头要有 X-Request-Id 属性并且值为整数的正则表达式
- Host=**.atguigu.com
- Method=GET  #请求方式是 GET
- Query=username,\d+ #要有参数名 username 并且值还要是证书才能路由

因为网关实际上也是通过http和其他微服务通信,也可以配置负载均衡规则(service-service)

@Configuration
@LoadBalancerClients(defaultConfiguration = GatewayConfig.class)
public class GatewayConfig {
    @Bean
    public ReactorLoadBalancer specLoadBalancer(Environment environment, LoadBalancerClientFactory loadBalancerClientFactory) {
        String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
        return new RoundRobinLoadBalancer(loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name);
    }
}

其他功能:过滤

yml中配置默认过滤default-filters

或配置全局过滤器,可以指定order

@Component
public class GatewayFilter implements GlobalFilter {
    @Override
    public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();
        log.info("gateway" + request.getURI().toString());
        return chain.filter(exchange);
    }
}

你可能感兴趣的:(Java,java)