1 Star 0 Fork 0

chuanzhang / spring-cloud-nacos

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README

spring-cloud-nacos

父依赖

            <!--nacos的管理依赖-->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>2.2.5.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

子模块依赖

        <!--nacos-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
    </dependencies>

yml 配置

spring:
  cloud:
    nacos:
      server-addr: localhost:8848 # nacos服务地址

Nacos 服务分级存储模型

  • 一级是服务: 例如userserver
  • 二级是集群: 例如:上海,杭州
  • 三级是实例,例如杭州机房的某台部署了userserver的服务器

服务跨集群调用问题:

服务调用尽可能选择本地集群的服务,跨集群调用延迟较高本地集群不可访问时,再去访问其他集群

服务集群属性

修改application.yml添加以下内容

spring:
  cloud:
    nacos:
      server-addr: localhost:8848 # nacos服务地址
      discovery:
      cluster-name: HZ # 配置集群名称,也就是机房位置

将order-server中设置负载均衡的IRule为NacosRule,这个规则优先会寻找与自己同集群的服务

userserver:
  ribbon:
    NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule # 负载均衡规则

根据权重负载均衡

实际部署中会出现这样的场景:

  • 服务器设备性能有差异,部分实例所在及其性能较好,另一些较差,我们希望性能好的机器承担更多的用户请求
    Nacos提供了权重配置来控制访问频率,权重越大则访问频率越高权重(0~1之间)

环境隔离 - namespace

Nacos中服务存储和数据存储的最外层都是一个名为namespace的东西,用来做最外层隔离 修改order-server的application.yml,添加namespace:

spring:
  cloud:
    nacos:
      server-addr: localhost:8848 # nacos服务地址
      discovery:
      cluster-name: HZ # 配置集群名称,也就是机房位置
      namespace:  # 填写命名空间: 填ID

不同namespace下的服务不可见

Nacos与Eureka对比

  1. Nacos与Eureka的共同点
  • 都支持服务注册和服务拉取
  • 都支持服务提供者心跳方式做健康检测
  1. Nacos与Eureka的区别
  • Nacos支持服务端主动检测提供者状态:临时实例采用心跳模式,非临时实例采用主动检测模式
  • 临时实例心跳不正常会被剔除,非临时实例则不会被剔除
  • Nacos支持服务列表变更的消息推送模式,服务列表更新更及时
  • Nacos集群默认采用AP方式,当集群中存在非临时实例时,采用CP模式,Eureka采用AP方式

Nacos 统一配置管理

配置获取步骤

  1. 引入Nacos的配置管理客户端依赖(导入到需要在nacos配置的模块)
<!--        nacos的配置管理依赖-->
<dependency>
  <groupId>com.alibaba.cloud</groupId>
  <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
        <!-- 若bootstrap配置不生效,加入以下依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
<version>3.0.1</version>
</dependency>
  1. 在微服务中添加bootstrap.yml配置文件,配置nacos地址,当前环境,服务名称,文件名和后缀。这些决定了程序启动时去nacos读取哪个文件
spring:
  application:
    name: userserver
  profiles:
    active: dev  # 环境
  cloud:
    nacos:
      server-addr: localhost:8848  # Nacos地址
      config:
        file-extension: yaml # 文件后缀名

配置自动更新

  1. 在相关类上添加注解 @RefreshScope
  2. 使用@ConfigurationProperties注解
@Component
@Data
@ConfigurationProperties(prefix = "pattern")
public class PatternProperties{
    private String dateformat;
}

多环境配置共享

多种配置的优先级:
服务名-profile.yaml -> 服务名.yaml > 本地配置
当前环境配置 优先级高于 nacos中的配置 优先级高于 本地配置

集群搭建步骤:

  1. 搭建MySQL集群并初始化数据库表
  2. 下载解压nacos
  3. 修改集群配置(节点信息),数据库配置
  4. 分别启动多个nacos节点
  5. nginx反向代理

Feign 使用步骤

  1. 引入依赖
<!--        feign客户端-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
  1. 在项目启动类中添加@EnableFeignClients注解
  2. 编写FeignClient接口
@FeignClient("userserver")
public interface UserClients {

    @GetMapping("/user/{id}")
    User findById(@PathVariable("id") Long id);
}
  1. 使用FeignClient中定义的方法代替RestTemplate
    public Order queryOrderById(Long orderId){
        Order order = orderMapper.findById(orderId);
        // 用feign远程调用
        User user = userClients.findById(order.getUserId());
        order.setUser(user);
        return order;
    }

Feign的自定义配置

配置Feign日志有两种方式

方式一:配置文件方式

  1. 全局生效
# Feign日志配置
feign:
  client:
    config:
      default:
        loggerLevel: FULL

方式二:代码方式先声明一个Bean

@Bean
public Logger.Level feignLoggerLevel(){
    return Logger.Level.FULL;
}
// 1. 而后如果是全局配置,则把他放到@EnableFeignClients注解中
@EnableFeignClients(defaultConfiguration = FeignClientConfiguration.class)
// 2. 如果是局部配置,则把他放到@FeignClient注解中
@FeignClient(value = "userserver", configuration = FeignClientConfiguration.class)

Feign的性能优化

Feign底层的客户端实现

  • URLConnection:默认实现,不支持连接池
  • Apache HttpClient:支持连接池
  • OKHttp:支持连接池 因此优化Feign的性能主要包括:
  1. 使用连接池代替默认的URLConnection
  2. 日志级别,最好用basic或none

Feign 添加HttpClient的支持

引入依赖

<!--        引入HttpClient依赖-->
        <dependency>
            <groupId>io.github.openfeign</groupId>
            <artifactId>feign-httpclient</artifactId>
        </dependency>

配置文件

# 开启httpClient配置
  httpclient:
    enabled: true #支持httpClient开关
    max-connections: 200 # 最大连接数
    max-connections-per-route: 50 # 单个路径的最大连接数

Feign的优化:

  • 日志级别尽量用basic
  • 使用HttpClient或者OKHttp代替URLConnection
    • 引入feign-httpClient依赖
    • 配置文件开启httpClient功能,设置连接池参数

Feign的最佳实践

spring官方不推荐使用

实现方式二--- 抽取FeignClient--->feign-api模块

实现最佳实践方式二的步骤如下:
1.首先创建一个module,命名为feign-api,然后引入feign的starter依赖
2.将order-service中编写的UserClient、User、DefaultFeignConfiguration都复制到feign-api项目中
3.在order-service中引入feign-api的依赖
4.修改order-service中的所有与上述三个组件有关的import部分,改成导入feign-api中的包
5.重启测试
推荐第二种

统一网关Gateway

网关功能:

  • 身份认证和权限校验
  • 服务路由,负载均衡
  • 请求限流

搭建网关步骤

  1. 创建新的module,引入SpringCloudGateway依赖和Nacos的服务发现依赖
<!--        nacos服务发现依赖-->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
        <!--        网关gateway依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
  1. 编写路由配置及其nacos地址
server:
  port: 10010  # 网关端口
spring:
  application:
    name: gateway # 服务名
  cloud:
    nacos:
      server-addr: localhost:8848 # nacos地址
      # gateway配置
    gateway:
      routes: # 网关路由配置
        - id: user-server  # 路由id,自定义主要是唯一即可
#          uri: http://127.0.0.1:8081 # 路由的目标地址  固定地址
          uri: lb://userserver # 路由的目标地址 lb就是负载均衡,后面跟服务名称
          predicates: # 路由断言,也就是判断请求是否符合路由规则的条件
            - Path=/user/**  # 这个是按照路径匹配, 只要以/user/开头就符合要求
        - id: order-server
          uri: lb://orderserver
          predicates:
            - Path=/order/**

路由断言工厂

  • After:在指定的时间后进行路由 例如
predicates:
  - After=2021-01-01T11:37:34.485+08:00[Asia/Shanghai]
  • Before:在指定的时间进行路由 例如:
predicates:
  - Before=2021-01-01T11:37:34.485+08:00[Asia/Shanghai]
  • Between:在指定的两个时间之间进行路由 例如:
predicates:
  - Between=2021-01-01T11:37:34.485+08:00[Asia/Shanghai], 2021-01-07T11:37:34.485+08:00[Asia/Shanghai]
  • Cookie:cookie匹配 例如:
predicates:
  - Cookie=username, zhangsan
  • Header:请求头匹配 例如:
predicates:
  - Header=X-Request-Id, \d+
  • Host:请求主机地址 例如:
predicates:
  - Host=**.abc.org, **.xyz.org
  • Method:请求方式 例如:
predicates:
  - Method=GET
  • Path:请求路径 例如:
predicates:
  - Path=/foo/{segment}
  • Query:请求参数 例如:
predicates:
  - Query=myParam, \d+
  • RemoteAddr:IP地址 例如:
predicates:
  - RemoteAddr=192.168.1.1/24
  • Weight:路由权重处理 例如:
predicates:
  - Weight=group1, 5
  - Weight=group2, 10

路由过滤器 GatewayFilter

给所有进入userserver的请求加一个请求头

// 实现方法
          ## 添加过滤
                  #          filters:
                  #            - AddRequestHeader=Truth, XYZ
                  - id: order-server
                  uri: lb://orderserver
                  predicates:
                  - Path=/order/**
 # 全局过滤配置
 default-filters:
 - AddRequestHeader=Truth,ABC

过滤器的作用是什么?
对路由的请求或响应做加工处理,比如添加请求头配置在路由下的过滤器只对当前路由的请求生效
defaultFilters的作用是什么?
对所有路由生效的过滤器,比如添加请求头配置在defaultFilters下过滤器对所有路由的请求都生效

全局过滤器GlobalFilter

@Component
//@Order(-1) // 优先级
public class AuthorizeFilter implements GlobalFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 1. 获取请求参数
        ServerHttpRequest request = exchange.getRequest();
        MultiValueMap<String, String> params = request.getQueryParams();
        // 2. 获取参数中的authorization 参数
        String auth = params.getFirst("authorization");
        // 3. 判断参数值是否等于 admin
        if ("admin".equals(auth)){
            // 4. 是 放行
            return chain.filter(exchange);
        }
        exchange.getResponse().setRawStatusCode(401);
        // 5. 否拦截
        return exchange.getResponse().setComplete();
    }

    // 优先级
    @Override
    public int getOrder() {
        return -1;
    }
}

全局过滤器的作用是什么?对所有路由都生效的过滤器,并且可以自定义处理逻辑
实现全局过滤器的步骤?

  • 实现GlobalFilter接口
  • 添加@Order注解或实现Ordered接口
  • 编写处理逻辑

过滤器的执行顺序

跨域问题处理

spring:
  cloud:
    gateway:
      globalcors:
        add-to-simple-url-handler-mapping: true # 解决options请求被拦截问题
        corsConfigurations:
          '[/**]':
            allowedOrigins:  # 允许哪些网站的跨域请求
              #              - "http://localhost:8080"
              - "*"
            allowedMethods:  # 允许的跨域的ajax的请求方式
              -  "GET"
              -  "POST"
              -  "PUT"
              -  "DELETE"
              -  "OPTIONS"
            allowedHeaders: "*"  # 允许在请求中携带的头信息
            exposedHeaders: true  # 是否允许请求中携带cookie
            maxAge: 36000  # 这次跨域检测的有效期

空文件

简介

springCloud+nacos整合 展开 收起
Java
取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
1
https://gitee.com/shang2-8-5/spring-cloud-nacos.git
git@gitee.com:shang2-8-5/spring-cloud-nacos.git
shang2-8-5
spring-cloud-nacos
spring-cloud-nacos
master

搜索帮助