springCloud-Nacos

1.服务注册

1.1 在父工程中添加spring-cloud-alibaba的管理依赖.

  • 在原有 spring-Cloud-dependencies的基础上加上spring-cloud-alibaba的管理依赖:

 <!--spring cloud alibaba-->
            <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>

注册服务的pom文件

 <!--spring boot parent -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.9.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <!--坐标-->
    <groupId>com.nanoswarm</groupId>
    <artifactId>nacosparent</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>nacosparent</name>
    <description>Demo project for Spring Boot</description>

    <!--打包方式-->
    <packaging>pom</packaging>

    <!--版本配置-->
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <spring-cloud.version>Hoxton.SR10</spring-cloud.version>
        <mysql.version>5.1.47</mysql.version>
        <mybatis.version>2.1.1</mybatis.version>
    </properties>

    <!--版本溯源-->
    <dependencyManagement>
        <dependencies>
            <!--spring cloud-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <!--spring cloud alibaba-->
            <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>

            <!--mysql-->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>${mysql.version}</version>
            </dependency>

            <!--mybatis-->
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>${mybatis.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <!--依赖-->
    <dependencies>
      <!--lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

1.2 在注册的服务中心添加依赖

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

1.3 yml

spring:
  cloud:
    nacos:
      server-addr: localhost:8848

2.服务多级存储模型

  • 以机房划分集群,分成三级.

 修改服务所在的集群

spring:
  cloud:
    nacos:
      server-addr: localhost:8848
      discovery:
        cluster-name: HZ #配置集群名称,也就是机房位置,例如 HZ 杭州

3.NacosRule负载均衡策略

  • 在服务设置了集群之后,不会走同集群优先访问的负载均衡策略,需要对Ribbon负载均衡策略进行配置.

#NacosRule负载均衡
user-service:
  ribbon:
    NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule

NacosRule : 优先访问同集群(HZ),在同集群内进行随机负载均衡策略.

4.Nacos服务实例权重设置

  • 在Nacos控制台可以设置实例的权重值,首先选中实例后面的编辑按钮

 将权重设置为0.1,测试可以发现8081被访问到的频率大大降低

  • 将权重设置为0,则完全不会被访问,可以用于灰度发布

5.Nacos 环境隔离

  • Nacos中服务存储和数据存储的最外层都是一个名为namespace的东西,用来做最外层隔离

spring:
  cloud:
    nacos:
      server-addr: localhost:8848
      discovery:
        namespace: namespace-name #  填命名空间的Id  可能用于项目环境 : 开发 , 测试 , 生产 环境

6.Eureka 与 Nacos

  • 向Nacos注册的实例默认为临时实例.

spring:
  cloud:
    nacos:
      server-addr: localhost:8848
      discovery:
        ephemeral: false   //false : 永久实例

7.配置管理

7.1 Nacos 创建配置管理

  • DataId : 服务名-profile.文件后缀

7.2 微服务配置拉取

服务拉取配置信息的优先级 : bootstrap.yml-远程配置中心-application.yml.

所以将Nacos配置管理的DataId的组成部分放入到Bootstap.yml中,以读取配置文件中的信息,再与application.yml做合并.

  • 添加Nacos配置依赖

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

编写Bootstrap.yml

spring:
  application:
    name: user-service
  profiles:
    active: dev
  cloud:
    nacos:
      server-addr: localhost:8848
      config:
        file-extension: yaml

7.3 配置热更新

  • 创建配置文件

    • 使用@ConfigurationProperties(prefix = "pattern")

@Component
@Data
@ConfigurationProperties(prefix = "pattern") //远程配置中心
public class PatternConfig {
    private String dateformat;
    private String envConfig;
}

7.4 多环境配置共享

开发 , 生产 , 测试的公用配置

  • 微服务启动时会从nacos读取多个配置文件

    • [spring.application.name]-[spring.profiles.active].yaml,例如:user-service-dev.yaml

    • [spring.application.name].yaml,例如:user-service.yaml

  • 无论profile如何变化,[服务名].yaml这个文件一定会加载,因此多环境共享配置可以写入这个文件

  • 配置服务环境

8.Feign

1.使用

  • 引入依赖

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

在启动类添加注解 @EnableFeignClients

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

编写声明式客户端

@FeignClient("user-service")
public interface UserClient {
    @GetMapping("/user/one/{id}")
    String queryUserById(@PathVariable("id") Long id);
}

远程调用

@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    private UserClient userClient;

    @Override
    public String selectOrderUserInfo(Long id) {
        String orderInfo = "this is the information of order where id = " + id+" ";
        String userInfo = userClient.queryUserById(id);
        return orderInfo + userInfo;
    }
}

9.Feign自定义配置

  • Feign运行自定义配置来覆盖默认配置,通常修改Feign的配置级别

#feign 日志级别
feign:
  client:
    config:
       user-service:
          loggerLevel: NONE

如果想看到日志则必须把SpringBoot的配置级别开启(进行配置,不能不写)

#日志级别
logging:
  level:
    com.nanoswarm: debug

10.性能优化

  • Feign底层可客户端实现

    • URLConnection : 默认实现,不支持连接池 //JDK自带

    • Apache HttpClient : 支持连接池

    • OKHttp : 支持连接池

  • 因此优化Feign的性能主要包括

    • 使用连接池替代默认的URLConnection

    • 日志级别 , 最好使用basic或none

10.1 引入依赖

<!--httpClient-->
        <dependency>
            <groupId>io.github.openfeign</groupId>
            <artifactId>feign-httpclient</artifactId>
        </dependency>

10.2 添加配置

#feign 日志级别
feign:
  client:
    config:
       user-service:
          loggerLevel: NONE
  httpclient:
    enabled: true
    max-connections: 200
    max-connections-per-route: 50 

11.网关

  • 网关功能:

    • 身份认证和权限校验

    • 服务路由,负载均衡

    • 请求限流

11.1 搭建

  • pom

 <dependencies>
        <!--gateway-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>

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

application.yml

spring:
  application:
    name: gateway-service
  cloud:
    nacos:
      server-addr: localhost:8848
    gateway:
      routes:
        - id: userServiceRounte #路由id,自定义,唯一即可
          uri: lb://user-service #路由目标地址
          predicates: #路由断言,判断请求是否符合路由规则条件
            - Path=/user/**

11.2 路由断言工厂

在路由配置的predicates中不仅仅可以配 - Path 还可以配很多其他东西.详见 Spring Cloud Gateway

  predicates: #路由断言,判断请求是否符合路由规则条件
            - Path=/user/**
            - After=2017-01-20T17:42:47.789-07:00[Asia/Shanaghai] //在2017年之后才能访问

11.3 路由过滤器

  • Spring提供了31种不同的路由过滤器工厂,详见如下.

Spring Cloud Gateway

spring:
  application:
    name: gateway-service
  cloud:
    nacos:
      server-addr: localhost:8848
    gateway:
      routes:
        - id: userServiceRounte #路由id,自定义,唯一即可
          uri: lb://user-service #路由目标地址
          predicates: #路由断言,判断请求是否符合路由规则条件
            - Path=/user/**
            - After=2017-01-20T17:42:47.789-07:00[Asia/Shanaghai]
          filter:
            - AddRequestHeader=AddRequestHeaderKey, AddRequestHeaderValue

获取相应头 (在user-service里面接收请求头)

  @GetMapping("/one/{id}")
    public String queryOrderUserInfoByOrderId(@PathVariable("id") Long id,
                                              @RequestHeader("AddRequestHeaderKey") String AddRequestHeaderValue ){
        System.out.println("由默认过滤器添加的请求头为 "+AddRequestHeaderValue);
        return orderService.selectOrderUserInfo(id);
    }

默认过滤器

在全局加过滤 : 对所有请求都生效

default-filters:
        - AddRequestHeader=AddRequestHeaderKey,AddRequestHeaderValue
spring:
  application:
    name: gateway-service
  cloud:
    nacos:
      server-addr: localhost:8848
    gateway:
      routes:
        - id: userServiceRounte #路由id,自定义,唯一即可
          uri: lb://user-service #路由目标地址
          predicates: #路由断言,判断请求是否符合路由规则条件
            - Path=/user/**
            - After=2017-01-20T17:42:47.789-07:00[Asia/Shanaghai]
        - id: orderServiceRounte
          uri: lb://order-service
          predicates:
            - Path=/order/**
      default-filters:
        - AddRequestHeader=AddRequestHeaderKey,AddRequestHeaderValue

11.4 全局过滤器

  • 全局过滤器的作用也是处理一切进入网关的请求和微服务响应,与GatewayFilter的作用一样。 区别在于GatewayFilter通过配置定义,处理逻辑是固定的。而GlobalFilter的逻辑需要自己写代码实现。 定义方式是实现GlobalFilter接口。

public interface GlobalFilter{
    /**  处理当前请求,有必要的话通过{@link GatewayFilterChain}将请求交给下一个过滤器处理
    * @param exchange 请求上下文,里面可以获取Request、Response等信息  
    * @param chain 用来把请求委托给下一个过滤器    
    * @return {@code Mono<Void>} 返回标示当前过滤器业务结束 */
    Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain);
}

案例 :

  • 需求:定义全局过滤器,拦截请求,判断请求的参数是否满足下面条件:

    • 参数中是否有password

    • password参数值是否为123456

  • 如果同时满足则放行,否则拦截

@Order(-1)
@Component
public class authorizedFilter implements GlobalFilter {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        MultiValueMap<String, String> queryParams = exchange.getRequest().getQueryParams();
        String password = queryParams.getFirst("password");
        if("123456".equals(password)){
           return chain.filter(exchange);
        }
        exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
        return exchange.getResponse().setComplete();
    }
}

11.5 过滤器链执行顺序

  • 每一个过滤器都必须指定一个int类型的order值,order值越小,优先级越高,执行顺序越靠前。

  • GlobalFilter通过实现Ordered接口,或者添加@Order注解来指定order值,由我们自己指定

  • 路由过滤器和defaultFilter的order由Spring指定,默认是按照声明顺序从1递增。

.

  • 当过滤器的order值一样时,会按照以下顺序执行,也就是说排序先看@Order()的值,如果值一样......

  • 默认过滤器 default-filters

  • |

  • 路由过滤器 filter

  • |

  • 全局过滤器 GlobalFilter

11.6 跨域

  • 跨域配置

globalcors:
        add-to-simple-url-handler-mapping: true #是否允许option请求
        cors-configurations:
          '[/**]':
            allowedOrigins:
              - "http:localhost:8090"
            allowedMethod:
              - "GET"
              - "DELETE"
              - "POST"
              - "PUT"
              - "OPTIONS"
            allowedHeaders: "*" #允许在请求中携带的头信息
            allowedCredentials: true #是否允许携带cookie
            maxAge: 360000 #这次跨域检测的有效期

yaml

server:
  port: 10010
spring:
  application:
    name: gateway-service
  cloud:
    nacos:
      server-addr: localhost:8848
    gateway:
      routes:
        - id: userServiceRounte #路由id,自定义,唯一即可
          uri: lb://user-service #路由目标地址
          predicates: #路由断言,判断请求是否符合路由规则条件
            - Path=/user/**
            - After=2017-01-20T17:42:47.789-07:00[Asia/Shanaghai]
        - id: orderServiceRounte
          uri: lb://order-service
          predicates:
            - Path=/order/**
      default-filters:
        - AddRequestHeader=AddRequestHeaderKey,AddRequestHeaderValue
      globalcors:
        add-to-simple-url-handler-mapping: true
        cors-configurations:
          '[/**]':
            allowedOrigins:
              - "http:localhost:8090"
            allowedMethod:
              - "GET"
              - "DELETE"
              - "POST"
              - "PUT"
              - "OPTIONS"
            allowedHeaders: "*"
            allowedCredentials: true
            maxAge: 360000 #这次跨域检测的有效期,不用每次ajax每次都询问服务器一次

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值