Nacos入门


一、Nacos

Nacos是SpringCloudAlibaba的组件,而SpringCloudAlibaba也遵循SpringCloud中定义的服务注册、服务发现规范。因此使用Nacos和使用Eureka对于微服务来说,并没有太大区别。

Nacos的服务类型分为两类:

  • 临时实例:如果实例宕机超过一定时间,会从服务列表剔除,默认的类型。

  • 非临时实例:如果实例宕机,不会从服务列表剔除,也可以叫永久实例。

spring:
  cloud:
    nacos:
      discovery:
        ephemeral: false # 设置为非临时实例

Nacos与eureka的共同点

  • 都支持服务注册和服务拉取
  • 都支持服务提供者心跳方式做健康检测

Nacos与eureka的区别

  • Nacos支持服务端主动检测提供者状态:临时实例采用心跳模式,非临时实例采用主动检测模式
  • 临时实例心跳不正常会被剔除,非临时实例则不会被剔除
  • Nacos支持服务列表变更的消息推送模式,服务列表更新更及时
  • Nacos集群默认采用AP方式,当集群中存在非临时实例时,采用CP模式;Eureka采用AP方式

二、Nacos注册中心

  • 1)引入依赖
//父工程中引入SpringCloudAlibaba的依赖
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-alibaba-dependencies</artifactId>
    <version>2.2.6.RELEASE</version>
    <type>pom</type>
    <scope>import</scope>
</dependency>
//引入nacos-discovery依赖:
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
  • 2)配置nacos地址
//application.yml中添加nacos地址:
spring:
  cloud:
    nacos:
      server-addr: localhost:8848
  • 3)重启微服务,登录nacos管理界面

三、服务分级存储模型

1).集群

一个服务可以包含多个集群,每个集群下可以有多个实例,形成分级模型,如图:
在这里插入图片描述
微服务互相访问时,应该尽可能访问同集群实例,因为本地访问速度更快。当本集群内不可用时,才访问其它集群。


  • 配置集群: 修改application.yml文件,添加集群配置
spring:
  cloud:
    nacos:
      server-addr: localhost:8848
      discovery:
        cluster-name: HN # 集群名称
  • 权重配置

在实际部署项目中,服务器性能存在差异,默认情况下NacosRule是同集群随机选择,Nacos提供了通过配置权重来控制访问频率,权重越大访问频率越高。

2).环境隔离

Nacos提供了namespace来实现环境隔离功能

  • nacos中可以有多个namespace
  • namespace下可以有group、service等
  • 不同namespace之间相互隔离,例如不同namespace的服务互相不可见

  • 给微服务配置namespace
//yml文件中添加
 namespace: 492a7d5d-237b-46a1-a99a-fa8e98e4b0f9 # 命名空间,填ID

四.Nacos配置管理

1)统一配置管理

在这里插入图片描述


在这里插入图片描述

从微服务拉取配置

微服务要拉取nacos中的配置信息,并且与本地yml文件中的配置合并才能完成项目启动。
spring引入了一种新的配置文件:bootstrap.yaml文件,会在application.yml之前被读取,流程如下:

在这里插入图片描述


  • 引入依赖
<!--nacos配置管理依赖-->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
  • 添加bootstrap.yml文件
spring:
  application:
    name: userservice # 服务名称
  cloud: #nacos注册中心配置内容
    nacos:
      discovery:
        server-addr: 192.168.94.129:8848
        cluster-name: HZ
        #开发环境的区别
        namespace: 73be46a4-c53c-4b10-a68f-205698afef0e
        #区分统一环境下的不同项目组
        group: cloud_project
      config:
        server-addr: 192.168.94.129:8848
        cluster-name: HZ
        namespace: 73be46a4-c53c-4b10-a68f-205698afef0e
        group: cloud_project
        file-extension: yml
#修改日志级别,可以显示出读取的配置信息
logging:
  level:
    cn.itcast: debug
    com:
      alibaba:
        cloud:
          nacos:
            client: debug

2)配置热更新

热更新的作用是在修改nacos的配置后,微服务不用重启也可以让配置生效。

  • 方式1、在@Value注入的变量所在类上添加注解@RefreshScope:
@Slf4j
@RestController
@RequestMapping("/user")
@RefreshScope  
public class UserController {
	
	@Value("${pattern.dateformat}")
    private String dateformat;
}
  • 方式2、使用@ConfigurationProperties注解代替@Value注解。

在user-service服务中,添加一个类,读取patterrn.dateformat属性:

@Component
@Data
@ConfigurationProperties(prefix = "pattern")
public class PatternProperties {
    private String dateformat;
}

在userController中替代@Value

@Slf4j
@RestController
@RequestMapping("/user")
public class UserController {
 @Autowired
    private PatternProperties properties;
}

3)多环境支持

​ 项目开发过程中,可能会存在多种环境,并且每一种环境所设置的配置都是不同的。nacos可以同时支持多环境配置,可以满足生产环境下的需求。

​ 不同的开发环境:namespace 区分

​ 不同的开发组:group 区分

​ 不同的项目: dataid 区分

​ 不同种类的配置:profile


在nacos配置中心中根据dataid进行区分即可。dataid 完整的拼接格式如下:
$ {prefix}-$ {spring.profiles.active}.${file-extension}

  • prefix 默认为 spring.application.name 的值,也可以通过配置项 spring.cloud.nacos.config.prefix来配置。
  • spring.profiles.active 即为当前环境对应的 profile
  • file-extension 为配置内容的数据格式,可以通过配置项 spring.cloud.nacos.config.file-extension来配置。

在这里插入图片描述


4)配置共享

微服务开发时,多个微服务中会配有相同的配置信息,造成配置冗余。

  • 在nacos中添加配置
    在这里插入图片描述
  • 在bootstrap.yml中添加:
spring:
  cloud:
    nacos:
      config:
        shared-configs:
          - dataId: 

5)持久化配置

nacos对于服务的配置信息保存到了自己内部的数据库:derby,一般在开发环境下需要让nacos读取外部数据库配置信息,方便后期的维护:

在这里插入图片描述


  • 1)新建数据库
  • 2)进入nccos容器中
docker exec -it nacos /bin/bash
  • 3)修改application.properties文件
spring.datasource.platform=mysql
db.num=1
db.url.0=jdbc:mysql://ip:3306/库名?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
db.user=
db.password=
  • 4)重启nacos容器

五、Feign远程调用

Feign是一个声明式的http客户端,官方地址:https://github.com/OpenFeign/feign

Fegin的使用步骤如下:

  • 1)引入依赖
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
  • 2)添加注解开启Feign功能
@EnableFeignClients
//开启全局日志记录
//@EnableFeignClients(defaultConfiguration = DefaultFeignConfiguration.class)
@MapperScan("cn.itcast.order.mapper")
@SpringBootApplication
public class OrderApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class, args);
    }
  • 3)编写FeignClient接口
  • 4)使用FeignClient中定义的方法代替RestTemplate

1)Feign的自定义配置

类型作用说明
feign.Logger.Level修改日志级别包含四种不同的级别:NONE、BASIC、HEADERS、FULL
feign.codec.Decoder响应结果的解析器http远程调用的结果做解析,例如解析json字符串为java对象
feign.codec.Encoder请求参数编码将请求参数编码,便于通过http请求发送
feign. Contract支持的注解格式默认是SpringMVC的注解
feign. Retryer失败重试机制请求失败的重试机制,默认是没有,不过会使用Ribbon的重试

例:

  • 日志配置方式1、配置文件方式
feign:  
  client:
    config: 
      userservice: # 针对某个微服务的配置
      // default: 这里用default就是全局配置
        loggerLevel: FULL #  日志级别
//- NONE:不记录任何日志信息,这是默认值。
//- BASIC:仅记录请求的方法,URL以及响应状态码和执行时间
//- HEADERS:在BASIC的基础上,额外记录了请求和响应的头信息
//- FULL:记录所有请求和响应的明细,包括头信息、请求体、元数据。 
  • 方式2、代码格式
    先声明一个类,并设置日志级别
public class DefaultFeignConfiguration  {
    @Bean
    public Logger.Level feignLogLevel(){
        return Logger.Level.BASIC; // 日志级别为BASIC
    }
}
@EnableFeignClients
//开启全局日志记录
@EnableFeignClients(defaultConfiguration = DefaultFeignConfiguration.class)
@MapperScan("cn.itcast.order.mapper")
@SpringBootApplication
public class OrderApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class, args);
    }

2)Feign使用优化

Feign底层发起http请求,依赖于其它的框架。其底层客户端实现包括:

•URLConnection:默认实现,不支持连接池

•Apache HttpClient :支持连接池

•OKHttp:支持连接池

优化Feign:
使用其他连接池代替URL默认
日志级别使用basic


例:

  • 1)连接Apache HttpClient 引入依赖
<!--httpClient的依赖 -->
<dependency>
    <groupId>io.github.openfeign</groupId>
    <artifactId>feign-httpclient</artifactId>
</dependency>
  • 2)配置连接池信息
feign:
  httpclient:
    enabled: true # 开启feign对HttpClient的支持
    max-connections: 200 # 最大的连接数
    max-connections-per-route: 100 # 每个路径的最大连接数

六、Gateway服务网关

Spring Cloud Gateway 是 Spring Cloud 的一个全新项目,该项目是基于 Spring 5.0,Spring Boot 2.0 和 Project Reactor 等响应式编程和事件流技术开发的网关,它旨在为微服务架构提供一种简单有效的统一的 API 路由管理方式。

核心功能特性:
权限控制:网关作为微服务入口,需要校验用户是是否有请求资格,如果没有则进行拦截。

路由和负载均衡:一切请求都必须先经过gateway,但网关不处理业务,而是根据某种规则,把请求转发到某个微服务,这个过程叫做路由。当然路由的目标服务有多个时,还需要做负载均衡。

限流:当请求流量过高时,在网关中按照下流的微服务能够接受的速度来放行请求,避免服务压力过大。

在SpringCloud中网关的实现包括两种:

  • gateway
  • zuul

Zuul是基于Servlet的实现,属于阻塞式编程。而SpringCloudGateway则是基于Spring5中提供的WebFlux,属于响应式编程的实现,具备更好的性能。


1)gateway入门操作

  • 1)引入依赖
<!--网关-->
<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!--nacos服务发现依赖-->
<dependency>
   <groupId>com.alibaba.cloud</groupId>
   <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
  • 2)编写启动类
  • 3)编写yml文件,(基本服务信息,nacos地址,路由等)
server:
  port: 10010 # 网关端口
spring:
  application:
    name: gateway # 服务名称
  cloud:
    nacos:
      server-addr: localhost:8848 # nacos地址
    gateway:
      routes: # 网关路由配置
        - id: user-service # 路由id,自定义,只要唯一即可
          # uri: http://127.0.0.1:8081 # 路由的目标地址 http就是固定地址
          uri: lb://userservice # 路由的目标地址 lb就是负载均衡,后面跟服务名称
          predicates: # 路由断言,也就是判断请求是否符合路由规则的条件
            - Path=/user/** # 这个是按照路径匹配,只要以/user/开头就符合要求
     # 全局的跨域处理
      globalcors:
        add-to-simple-url-handler-mapping: true # 解决options请求被拦截问题
        corsConfigurations:
          '[/**]':
            allowedOrigins:
              - "http://localhost:9001"
              - "http://localhost:9002"
              - "http://127.0.0.1:9001"
              - "http://127.0.0.1:9002"
            allowedMethods: # 允许的跨域ajax的请求方式
              - "GET"
              - "POST"
              - "DELETE"
              - "PUT"
              - "OPTIONS"
            allowedHeaders: "*" # 允许在请求中携带的头信息
            allowCredentials: true # 是否允许携带cookie
            maxAge: 360000 # 这次跨域检测的有效期

访问流程如下
在这里插入图片描述

2)断言工厂

yml配置文件中的断言规则是会被Predicate Factory读取处理,转换为路由判断的条件。

例:

名称说明示例
After是某个时间点后的请求- After=2037-01-20T17:42:47.789-07:00[America/Denver]
Before是某个时间点之前的请求- Before=2031-04-13T15:14:47.433+08:00[Asia/Shanghai]
Between是某两个时间点之前的请求- Between=2037-01-20T17:42:47.789-07:00[America/Denver], 2037-01-21T17:42:47.789-07:00[America/Denver]
Cookie请求必须包含某些cookie- Cookie=chocolate, ch.p
Header请求必须包含某些header- Header=X-Request-Id, \d+
Host请求必须是访问某个host(域名)- Host=.somehost.org,.anotherhost.org
Method请求方式必须是指定方式- Method=GET,POST
Path请求路径必须符合指定规则- Path=/red/{segment},/blue/**
Query请求参数必须包含指定参数- Query=name, Jack或者- Query=name
RemoteAddr请求者的ip必须是指定范围- RemoteAddr=192.168.1.1/24
Weight权重处理

3)过滤器工厂:

Spring提供了31种不同的路由过滤器工厂。
例:

名称说明
AddRequestHeader给当前请求添加一个请求头
RemoveRequestHeader移除请求中的一个请求头
AddResponseHeader给响应结果中添加一个响应头
RemoveResponseHeader从响应结果中移除有一个响应头
RequestRateLimiter限制请求的流量

例:

  • 修改yml添加过滤器配置:
	filters: # 过滤器   对当前路由的请求生效
        - AddRequestHeader=Truth, Itcast is freaking awesome! # 添加请求头
//default-filters: # 默认过滤项   对所有路由生效
		-

4)全局过滤器:

全局过滤器的作用和GatewayFilter的作用一样,不过处理逻辑需要自己定义。
实现方法是实现GlobaFilter接口

例:

//过滤器的执行顺序,order值一样时,会按照 defaultFilter > 路由过滤器 > GlobalFilter的顺序执行。
@Order(-1) 
@Component
public class AuthorizeFilter implements GlobalFilter {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 1.获取请求参数
        MultiValueMap<String, String> params = exchange.getRequest().getQueryParams();
        // 2.获取authorization参数
        String auth = params.getFirst("authorization");
        // 3.校验
        if ("admin".equals(auth)) {
            // 放行
            return chain.filter(exchange);
        }
        // 4.拦截
        // 4.1.禁止访问,设置状态码
        exchange.getResponse().setStatusCode(HttpStatus.FORBIDDEN);
        // 4.2.结束处理
        return exchange.getResponse().setComplete();
    }
}

5)跨域问题:

跨域问题:协议,域名,端口三者中任意一者不同即为跨域。浏览器禁止请求的发起者与服务端发生跨域ajax请求,请求被浏览器拦截的问题

解决方式:yml文件中添加以下配置

spring:
  cloud:
    gateway:
      # 。。。
      globalcors: # 全局的跨域处理
        add-to-simple-url-handler-mapping: true # 解决options请求被拦截问题
        corsConfigurations:
          '[/**]':
            allowedOrigins: "*" # 允许哪些网站的跨域请求 
            allowedMethods:      # 允许的跨域ajax的请求方式
              - "GET"
              - "POST"
              - "DELETE"
              - "PUT"
              - "OPTIONS"
            allowedHeaders: "*" # 允许在请求中携带的头信息
            allowCredentials: true # 是否允许携带cookie
            maxAge: 360000 # 这次跨域检测的有效期
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值