springboot框架项目实践应用十八(nacos高级特性)

1.引言

nacos是一个非常优秀的服务注册与发现组件,实际项目中,我们可能会用到它的常用高级特性,比如说

  • 实现服务优雅上下线
  • 服务领域模型

2.服务优雅上下线

在服务化架构体系下,服务优雅下线是重要且必要的一个能力。比如说线上服务升级,用户7*24小时在使用线上服务,我们不能简单粗暴的停机升级,停机意味着

  • 服务不可用,影响用户体验
  • 停机升级,时间成本高,时间就是金钱

因此线上服务,是不允许停机升级的。那么怎么去解决线上服务升级的问题呢?增加了新的特性、或者修复了线上bug,又不得不升级!

这个时候就显得服务化架构体系下,流量治理的重要性了。在实现流量治理的前提下,实现服务的灰度发布、或者蓝绿发布,当然这需要有一整套的服务治理体系,对研发团队的实力要求比较高!

如果我们是中小企业的研发团队,建立这样一套完整的服务治理体系,可能不太现实,可问题还是需要解决的,怎么办呢?有没有成本相对小的方案?

有,其实借助springboot actuator组件,以及服务注册发现组件Eureka、nacos,我们就可以很好的实现服务优雅下线,实现线上服务不停机升级。

这里,我们结合nacos服务注册发现,看如何来实现线上服务优雅下线。

2.1.准备环境

通过actuator组件实现线上服务下线,需要引入actuator组件依赖,以及服务注册发现组件依赖

xml 复制代码
<!--actuator依赖-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--nacos discovery依赖-->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

默认情况下,actuator组件只开放health端点、以及info端点

json 复制代码
// 20210814155152
// http://127.0.0.1:8080/actuator

{
  "_links": {
    "self": {
      "href": "http://127.0.0.1:8080/actuator",
      "templated": false
    },
    "health": {
      "href": "http://127.0.0.1:8080/actuator/health",
      "templated": false
    },
    "health-path": {
      "href": "http://127.0.0.1:8080/actuator/health/{*path}",
      "templated": true
    },
    "info": {
      "href": "http://127.0.0.1:8080/actuator/info",
      "templated": false
    }
  }
}

我们需要增加配置,开放服务下线端点

yaml 复制代码
#健康检查端点配置
management:
  endpoints:
    web:
      exposure:
      #暴露所有端点
        include: '*'
  endpoint:
    shutdown:
    #激活shutdown端点
      enabled: true
    health:
      show-details: always

2.2.优雅下线相关服务端点

引入actuator组件、nacos服务发现组件依赖后,重新启动服务,访问端点:http://127.0.0.1:8080/actuator

  • service-registry端点:通过该端点请求服务上线、或者下线
  • shutdown端点:通过该端点,停止服务
json 复制代码
/ 20210814155436
// http://127.0.0.1:8080/actuator

{
  "_links": {
    ...省略其它端点...
    "shutdown": {
      "href": "http://127.0.0.1:8080/actuator/shutdown",
      "templated": false
    },
   ...省略其它端点...
    "service-registry": {
      "href": "http://127.0.0.1:8080/actuator/service-registry",
      "templated": false
    }
  }
}

启动服务follow-me-springloud-nacos-provider,在nacos控制台,我们在服务列表看到服务在线,看到操作栏显示"下线",说明此时服务在线

请求端点:http://127.0.0.1:8080/actuator/service-registry?status=DOWN,将服务节点下线,操作栏显示"上线",说明服务已经下线,流量就不会再打到这个服务节点了

请求端点:http://127.0.0.1:8080/actuator/shutdown,停止服务节点应用

应用控制台,服务停止

nacos控制台服务列表,服务节点已经不在服务注册表中

2.3.完整演示服务上下线

案例演示步骤:

2.3.1.直接通过端点实现服务下线

服务都正常启动后,请求服务消费者端点:http://127.0.0.1:8090/consumer/test

服务消费者控制台

服务提供者8080实例控制台

服务提供者8081实例控制台

下线服务提供者8080实例,请求端点:http://127.0.0.1:8080/actuator/service-registry?status=DOWN

再次请求服务消费者端点:http://127.0.0.1:8090/consumer/test

服务消费者控制台

服务提供者8080实例控制台

服务提供者8081实例控制台

2.3.2.nacos控制台实现服务上下线

通过上面案例中service-registry端点实现服务上下线

如果我们使用的服务注册发现组件是Eureka,那就只能通过service-retistry端点来实现服务上下线控制了。

如果使用nacos,则方便了很多,通过nacos管理控制台面板,即可控制服务的上下线,比如通过控制台面板,我们再将8081服务提供者实例下线

下线前

下线后

请求服务消费者端点:http://127.0.0.1:8090/consumer/test,报错!因为已经没有可用的服务提供者节点了!

shell 复制代码
2021-08-14 16:35:32.790 ERROR 10012 --- [nio-8090-exec-9] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.IllegalStateException: No instances available for follow-me-springloud-nacos-provider] with root cause

2.3.3.项目实践建议

在实际项目中,要实现线上服务不停机升级,比如说有a/b/c三个节点实例,可以分步实现

  • 将a节点下线,升级完成上线
  • 将b节点下线,升级完成上线
  • 将c节点下线,升级完成上线

这样一来,即实现了线上服务不停机升级,且技术成本不高,正好借助springboot actuator组件、ribbon组件、服务注册发现组件完美整合,实现流量切分,实现灰度发布。

2.服务领域模型

nacos提供的服务领域模型,很好的满足实现了服务之间的隔离,领域模型范围从大到下依次是

  • 命名空间
  • 分组
  • 服务
  • 集群
  • 实例

用一个图来描述,是这样的

通过命名空间,可以实现不同环境的隔离,类似与profile特性,比如说:生产环境、测试环境、开发环境之间的隔离。

分组、服务是逻辑上的概念,暂时还没有用。

集群可用于实现同城双活、异地容灾。比如说为了实现异地容灾,将服务部署到了两个城市的两个机房中

  • 广州、深圳都部署了完整的服务集群,实现异地容灾
  • 这个时候,为了用户体验,以及性能,我们需要实现同集群中服务优先调用

3.1.环境之间隔离

nacos提供了默认的名称空间public

我们可以创建新的名称空间,我创建两个名称空间,分别表示开发环境、生产环境

  • 开发环境:dev
  • 生产环境:prod

将服务提供者follow-me-springloud-nacos-provider,配置为生产环境

yaml 复制代码
spring:
  application:
    name: follow-me-springloud-nacos-provider
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
        #配置名称空间 prod,配置值命名空间Id
        namespace: 206760b2-a6f4-4da3-bbe1-8c4c75dc7b2e

启动服务提供者,它注册prod环境下

将服务消费者follow-me-springloud-nacos-consumer,配置为开发环境

yaml 复制代码
spring:
  application:
    name: follow-me-springloud-nacos-consumer
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
        #配置名称空间 dev,配置值命名空间Id
        namespace: 1a500714-6fdc-410c-8743-ae30d0edf92e

启动服务消费者,它注册在dev环境下

此时,请求服务消费者端点:http://127.0.0.1:8090/consumer/test,报错!因为服务消费者,与服务提供者不在一个命名空间下,彼此之间隔离

3.2.同集群优先调用

演示完成不同命名空间隔离,我们将服务提供者,与服务消费者都恢复到dev环境,来看同集群优先调用。

增加集群配置

  • 服务提供者8080实例,部署到广州机房,即cluster-name:GZ
  • 服务提供者8081实例,部署到深圳机房,即cluster-name:SZ
  • 服务消费者实例,部署到广州机房,即cluster-name:GZ

配置案例,其它实例可参考修改配置

yaml 复制代码
spring:
  application:
    name: follow-me-springloud-nacos-provider
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
        #配置名称空间 prod,配置值命名空间Id
        #namespace: 206760b2-a6f4-4da3-bbe1-8c4c75dc7b2e
        #配置名称空间 dev
        namespace: 1a500714-6fdc-410c-8743-ae30d0edf92e
        #服务提供者8080实例,部署在广州机房
        cluster-name: GZ

配置ribbon负载均衡策略

将ribbon默认的轮询负载均衡策略,指定服务提供者配置为nacos提供的NacosRule,NacosRule实现了同机房优先调用

yaml 复制代码
#ribbon配置
ribbon:
  eager-load:
    #开启ribbon饥饿加载
    enabled: true
#服务提供者,使用nacos提供的负载均衡策略:同集群优先调用
follow-me-springloud-nacos-provider:
   ribbon:
     NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule

启动服务提供者8080实例,它在GZ机房

启动服务提供者8081实例,它在SZ机房

启动服务消费者实例,它在GZ机房,并访问端点:http://127.0.0.1:8090/consumer/test,观察到一直调用到服务提供者8080实例

下线服务提供者8080实例

再次请求服务消费者端点:http://127.0.0.1:8090/consumer/test,观察到此时会调用到服务提供者8081,部署在SZ机房的实例

本文源码:gitee.com/yanghouhua/...

相关推荐
whoarethenext3 小时前
qt的基本使用
开发语言·c++·后端·qt
Charlie__ZS4 小时前
SpringCloud - 分布式事务
分布式·spring·spring cloud
草捏子7 小时前
主从延迟导致数据读不到?手把手教你架构级解决方案
后端
橘猫云计算机设计7 小时前
基于Python电影数据的实时分析可视化系统(源码+lw+部署文档+讲解),源码可白嫖!
数据库·后端·python·信息可视化·小程序·毕业设计
lorogy7 小时前
【VSCode配置】运行springboot项目和vue项目
vue.js·spring boot·vscode
Yolo@~7 小时前
SpringBoot无法访问静态资源文件CSS、Js问题
java·spring boot·后端
大鸡腿同学8 小时前
资源背后的成事密码
后端
Asthenia04128 小时前
使用 Spring Cloud Gateway 实现四种限流方案:固定窗口、滑动窗口、令牌桶与漏桶
后端
老李不敲代码9 小时前
榕壹云门店管理系统:基于Spring Boot+Mysql+UniApp的智慧解决方案
spring boot·后端·mysql·微信小程序·小程序·uni-app·软件需求
海风极客9 小时前
Go小技巧&易错点100例(二十五)
开发语言·后端·golang