【java总结】框架之SpringCloud

SpringCloud基础

什么是 spring cloud?

spring cloud 是一系列框架的有序集合。是多种微服务架构落地技术的集合体,俗称微服务全家桶。

image-20200809203030808

SpringCloud组件

alibaba的统一放到下面那个模块说,这里复习传统框架

服务注册中心

Eureka

Eureka是netflix公司研发并且开源的一个服务发现组件。

Eureka组件包含注册中心(Eureka Server)和eureka客户端。

服务注册中心:Eureka客户端会把自身服务注册到注册中心,为其他Eureka客户端提供服务,Eureka客户端通过注册中心相互发现对应服务并进行调用

Eureka客户端:相对注册中心而言,所有注册到服务注册中心的服务都可以表述为Eureka客户端;但是站在提供方和消费方的角度看,Eureka客户端又可以称之为服务端

客户端有一个内置的,使用轮询的负载算法,向所有服务器发送心跳(默认30s),如果服务器多个心跳周期都没有接受到,就会从服务列表中把这个节点移除(默认90s)

使用流程

首先你要创建一个eureka的服务端,弄一个Model,然后给它的pom文件加上:

<!--eureka-server服务端 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>

表示这是一个eureka的服务端

然后在这个服务端的主启动类上加上注解:

@EnableEurekaServer //标注这是个eureka服务端

然后在编写yml配置文件:

server:
  port: 7001	#端口号
eureka:
  instance:
    hostname: localhost #eureka服务端的实例名称
  client:
    register-with-eureka: false     #false表示不向注册中心注册自己。
    fetch-registry: false     #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
    service-url:     #设置与Eureka  单机
       defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

这个服务端就算搭建好了,之后我们需要在我们的被调用方中配置,将其注册进我们的eureka中:

首先是pom文件:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>

然后在启动类上加上注解:

@EnableEurekaClient //本服务启动后会自动注册进eureka服务中,服务发现

最后依然是在配置文件中加上:

#客户端注册进rureka服务列表内
eureka:
  client:
    service-url:
      defaultZone: http://localhost:7001/eureka	#这个url就是服务端的url

首先启动我们的eureka服务端,再启动我们的客户端,也就是在微服务中被调用端

访问localhost:7001就会出现以下页面:红框就是我们注册进去的服务,出现在这里也就说明注册成功,这个服务名是根据客户端的配置文件中配置得来的.

image-20200809205030554

Eureka的集群

Eureka的集群很简单,在yml文件defaultZone配置多个地址即可

自我保护机制

  • 为了保证EurekaClient可以正常运行,当网络发生故障的时候,不应该删除客户端节点
  • 当某个节点短时间丢失过多客户端时,那么这个节点就会进入自我保护模式
  • 默认自我保护开启:eureka.server.enable-self-preservation = true

服务注册

服务提供者在启动时,会向EurekaServer发起一次请求,将自己注册到Eureka注册中心中去

服务续约

在注册服务完成以后,服务提供者会维持一个心跳 (每30s定时向EurekaServer发起请求), 告诉EurekaServer:“我还活着”。这个我们称为服务的续约(renew);

失效剔除

有些时候,我们的服务提供方并不一定会正常下线,可能因为内存溢出、网络故障等原因导致服务无法正常工作。Eureka Server需要将这样的服务剔除出服务列表。

因此它会开启一个定时任务,每隔60秒对所有失效的服务(超过90秒未响应)进行剔除。

其他问题

zookeeper和eureka的区别在哪?

eureka遵守AP原则,zookeeper遵守CP原则

CA-单点集群,满足一致性,可用性的系统,通常在可扩展性上不太强大
CP-满足一致性,分区容忍必的系统,通常性能不是特别高。
AP-满足可用性,分区容忍性的系统,通常可能对一致性要求低一些

image-20200809210412328

Zookeeper

zookeeper是一个分布式协调工具,可以实现注册中心功能

使用流程

首先启动Zookeeper服务器

然后创建一个服务提供者

pom引入相应的包

yml填写zookeeper服务器地址

主启动要加上@EnableDiscoveryClient注解 该注解用于向consul,zookeeper作为注册中心时注册服务

然后创建服务消费者

  • yml需要配置
  • pom引入相应的包
  • yml填写zookeeper服务器地址
  • 主启动要加上@EnableDiscoveryClient注解 该注解用于向consul,zookeeper作为注册中心时注册服务

Consul

Consul是一套开源的分布式服务发现和配置管理系统,Go语言开发的

使用流程和zookeeper类似

三个注册中心的异同点

image

image

服务调用

Ribbon

Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端,负载均衡的软件

负载均衡

集中式LB

即在服务的消费方和提供方之间使用独立的LB设施(可以是硬件,如F5, 也可以是软件,如nginx), 由该设施负责把访问请求通过某种策略转发至服务的提供方;

进程内LB

将LB逻辑集成到消费方,消费方从服务注册中心获知有哪些地址可用,然后自己再从这些地址中选择出一个合适的服务器。
Ribbon就属于进程内LB,它只是一个类库,集成于消费方进程,消费方通过它来获取到服务提供方的地址。

使用流程

先编写以下的配置文件:

spring:
    application:
        name: spring-cloud-ribbon
server:
    port: 8888
ping-server:
    ribbon:
        eureka:
            enabled: false
        listOfServers: localhost:9092,localhost:9999
        ServerListRefreshInterval: 15000

然后创建一个RestTemplate的bean

之后注入测试

@SpringBootApplication
@RestController
@RibbonClient(
name = "ping-a-server",
configuration = RibbonConfiguration.class)
public class ServerLocationApp {

    @LoadBalanced
    @Bean
    RestTemplate getRestTemplate() {
        return new RestTemplate();
    }

    @Autowired
    RestTemplate restTemplate;

    @RequestMapping("/server-location")
    public String serverLocation() {
        return this.restTemplate.getForObject(
            "http://ping-server/locaus", String.class);
    }

    public static void main(String[] args) {
        SpringApplication.run(ServerLocationApp.class, args);
    }
}

也可以通过bean来设置规则

主启动类添加@RibbonClient

Ribbon的负载算法

  • RoundRobinRule: 默认轮询的方式
  • RandomRule: 随机方式
  • WeightedResponseTimeRule: 根据响应时间来分配权重的方式,响应的越快,分配的值越大。
  • BestAvailableRule: 选择并发量最小的方式
  • RetryRule: 在一个配置时间段内当选择server不成功,则一直尝试使用subRule的方式选择一个可用的server
  • ZoneAvoidanceRule: 根据性能和可用性来选择。
  • AvailabilityFilteringRule: 过滤掉那些因为一直连接失败的被标记为circuit tripped的后端server,并过滤掉那些高并发的的后端server(active connections 超过配置的阈值)

OpenFeign

Feign是一个声明式的Web服务客户端,让编写Web服务客户端变得非常容易,只需 创建一个接口并在接口上添加注解即可

前面在使用Ribbon+RestTemplate时,利用RestTemplate对http请求进行封装,因此,Fergn是进一步的封装,Feign内置了Ribbon,用来做客户端负载均衡,OpenFeign是Spring Cloud 在Feign的基础上支持了Spring MVC的注解,如@RequesMapping等等。

OpenFeign的@FeignClient可以解析SpringMVC的@RequestMapping注解下的接口,并通过动态代理的方式产生实现类,实现类中做负载均衡并调用其他服务。

使用方法

主启动类增加 @EnableFeignClients 注解

在业务上面直接标注如:@FeignClient(name = “user-center”)

OpenFeign超时控制

OpenFeign默认等一秒钟,所以需要在yml配置文件中配置ribbon的等待时间

image

OpenFeign日志功能
  • 日志级别img

  • 配置日志Bean

    img

  • yml要开启日志

    img

服务降级

分布式面临的问题

复杂分布式体系结构中的应用程序有数十个依赖关系,每个依赖关系在某些时候将不可避免地失败。

  • 服务雪崩

假设存在如下调用链

image-20200809230835604

image-20200809230821438

如上图所示,一个服务失败,导致整条链路的服务都失败的情形,我们称之为服务雪崩。

怎么解决?服务熔断服务降级就可以视为解决服务雪崩的手段之一。

服务降级

服务器忙,请稍后再试,返回一个友好提示,fallback,或者启动备用方案

服务熔断

保险丝达到最大服务访问后,拉闸限电,然后调用服务降级的方法并返回友好提示

服务限流

秒杀高并发等操作,严禁一窝蜂的过来拥挤,大家排队,一秒钟N个,有序进行

Hystrix(豪猪哥)

Hystrix是一个用于处理分布式系统的延迟和容错的开源库,在分布式系统中,许多依赖不可避免的会调用失败,比如超时、异常等,Hystrix能够保证在一个依赖出问题的情况下,不会导致整个服务失败,避免级联故障,以提高分布式系统的弹性。

“断路器”本身是一种开关设置,当某个服务单元发生故障之后,通过断路器的故障监控(类似熔断保险丝),向调用方返回一个符合预期的,可处理的备选响应(FallBack),而不是长时间的等待或者抛出服务方无法处理的异常,这样就保证服务方调用线程不会被长时间、不必要的占用,从而避免故障在在分布式系统中的绵延,乃至雪崩。

使用流程

首先新建一个服务提供者

引入相应地pom

<!--Hystrix依赖-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>

然后配置yml

#服务实例名称修改
instance-id: lingluocloud-dept8001-hystrix

然后在业务类标注

@HystrixCommand(fallbackMethod = "paymentInfo_TimeOutHandler",commandProperties = {@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "3000") //3秒钟以内就是正常的业务逻辑

然后在主启动类 添加@EnableCircuitBreaker注解

解决代码膨胀

@DefaultProperties(defaultFallback = “”) //在controller类上标注,如果配置了兜底方法,就按照自己的来,如果没有的话就按照这里配置的

服务网关

gataway

SpringCloud在之前是使用的netflix公司zuul,后来zuul1的性能表现不是很理想,而且zuul2.0连续跳票,所以催生了spring团队开发了Gateway项目。

API网关封装了系统内部架构,为每个客户端提供一个定制的API。它可能还具有其它职责,如身份验证、监控、负载均衡、缓存、请求分片与管理、静态响应处理。API网关方式的核心要点是,所有的客户端和消费端都通过统一的网关接入微服务,在网关层处理所有的非业务功能。通常,网关也是提供REST/HTTP的访问API。

Nginx和gataway的区别

  • 像Nginx这类网关,性能肯定是没得说,它适合做那种门户网关,是作为整个全局的网关,是对外的,处于最外层的;而Gateway这种,更像是业务网关,主要用来对应不同的客户端提供服务的,用于聚合业务的。各个微服务独立部署,职责单一,对外提供服务的时候需要有一个东西把业务聚合起来。
  • 像Nginx这类网关,都是用不同的语言编写的,不易于扩展;而Gateway就不同,它是用Java写的,易于扩展和维护
  • Gateway这类网关可以实现熔断、重试等功能,这是Nginx不具备的

服务配置

Config

对于一些简单的项目来说,我们一般都是直接把相关配置放在单独的配置文件中,以 properties 或者 yml 的格式出现,更省事儿的方式是直接放到 application.properties 或 application.yml 中。但是这样的方式有个明显的问题,那就是,当修改了配置之后,必须重启服务,否则配置无法生效。

目前有一些用的比较多的开源的配置中心,比如携程的 Apollo、蚂蚁金服的 disconf 等,对比 Spring Cloud Config,这些配置中心功能更加强大。有兴趣的可以拿来试一试。

配置方式

最简单的配置中心,就是启动一个服务作为服务方,之后各个需要获取配置的服务作为客户端来这个服务方获取配置。

先在 github 中建立配置文件

data:
  env: config-eureka-dev
  user:
    username: eureka-client-user
    password: 123

创建配置中心服务端

新建 Spring Boot 项目,引入 config-server 和 starter-web

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!-- spring cloud config 服务端包 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-config-server</artifactId>
</dependency>

配置 config 相关的配置项

bootstrap.yml 文件

spring:
  application:
    name: config-single-server  # 应用名称
  cloud:
     config:
        server:
          git:
            uri: https://github.com/huzhicheng/config-only-a-demo #配置文件所在仓库
            username: github 登录账号
            password: github 登录密码
            default-label: master #配置文件分支
            search-paths: config  #配置文件所在根目录

application.yml

server:
  port: 3301

在 Application 启动类上增加相关注解 @EnableConfigServer

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

启动服务,接下来测试一下。新建 Spring Boot 项目,引入 config-server 和 starter-web

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!-- spring cloud config 服务端包 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-config-server</artifactId>
</dependency>

配置 config 相关的配置项

bootstrap.yml 文件

spring:
  application:
    name: config-single-server  # 应用名称
  cloud:
     config:
        server:
          git:
            uri: https://github.com/huzhicheng/config-only-a-demo #配置文件所在仓库
            username: github 登录账号
            password: github 登录密码
            default-label: master #配置文件分支
            search-paths: config  #配置文件所在根目录

application.yml

server:
  port: 3301

在 Application 启动类上增加相关注解 @EnableConfigServer

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

启动服务,接下来测试一下。

Spring Cloud Config 有它的一套访问规则,我们通过这套规则在浏览器上直接访问就可以。

/{application}/{profile}[/{label}]
/{application}-{profile}.yml
/{label}/{application}-{profile}.yml
/{application}-{profile}.properties
/{label}/{application}-{profile}.properties

{application} 就是应用名称,对应到配置文件上来,就是配置文件的名称部分,例如我上面创建的配置文件。

{profile} 就是配置文件的版本,我们的项目有开发版本、测试环境版本、生产环境版本,对应到配置文件上来就是以 application-{profile}.yml 加以区分,例如application-dev.yml、application-sit.yml、application-prod.yml。

{label} 表示 git 分支,默认是 master 分支,如果项目是以分支做区分也是可以的,那就可以通过不同的 label 来控制访问不同的配置文件了。

创建配置中心客户端,使用配置

配置中心服务端好了,配置数据准备好了,接下来,就要在我们的项目中使用它了。

1、引用相关的 maven 包。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!-- spring cloud config 客户端包 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-config</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

2、初始化配置文件

bootstrap.yml

spring:
  profiles:
    active: dev

---
spring:
  profiles: prod
  application:
    name: config-single-client
  cloud:
     config:
       uri: http://localhost:3301
       label: master
       profile: prod


---
spring:
  profiles: dev
  application:
    name: config-single-client
  cloud:
     config:
       uri: http://localhost:3301
       label: master
       profile: dev

配置了两个版本的配置,并通过 spring.profiles.active 设置当前使用的版本,例如本例中使用的 dev 版本。

application.yml

server:
  port: 3302
management:
  endpoint:
    shutdown:
      enabled: false
  endpoints:
    web:
      exposure:
        include: "*"

data:
  env: NaN
  user:
    username: NaN
    password: NaN

其中 management 是关于 actuator 相关的,接下来自动刷新配置的时候需要使用。

data 部分是当无法读取配置中心的配置时,使用此配置,以免项目无法启动。

3、要读取配置中心的内容,需要增加相关的配置类,Spring Cloud Config 读取配置中心内容的方式和读取本地配置文件中的配置是一模一样的。可以通过 @Value 或 @ConfigurationProperties 来获取。

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

4、要读取配置中心的内容,需要增加相关的配置类,Spring Cloud Config 读取配置中心内容的方式和读取本地配置文件中的配置是一模一样的。可以通过 @Value 或 @ConfigurationProperties 来获取。

使用 @Value 的方式:

@Data
@Component
public class GitConfig {

    @Value("${data.env}")
    private String env;

    @Value("${data.user.username}")
    private String username;

    @Value("${data.user.password}")
    private String password;

}

使用 @ConfigurationProperties 的方式:

@Component
@Data
@ConfigurationProperties(prefix = "data")
public class GitAutoRefreshConfig {

    public static class UserInfo {
        private String username;

        private String password;

        public String getUsername() {
            return username;
        }

        public void setUsername(String username) {
            this.username = username;
        }

        public String getPassword() {
            return password;
        }

        public void setPassword(String password) {
            this.password = password;
        }

        @Override
        public String toString() {
            return "UserInfo{" +
                    "username='" + username + '\'' +
                    ", password='" + password + '\'' +
                    '}';
        }
    }

    private String env;

    private UserInfo user;
}

实现自动刷新

在 config client 端配置中增加 actuator 配置,上面大家可能就注意到了。

management:
  endpoint:
    shutdown:
      enabled: false
  endpoints:
    web:
      exposure:
        include: "*"

其实这里主要用到的是 refresh 这个接口

2、在需要读取配置的类上增加 @RefreshScope 注解,我们是 controller 中使用配置,所以加在 controller 中。

@RestController
@RefreshScope
public class GitController {

    @Autowired
    private GitConfig gitConfig;

    @Autowired
    private GitAutoRefreshConfig gitAutoRefreshConfig;

    @GetMapping(value = "show")
    public Object show(){
        return gitConfig;
    }

    @GetMapping(value = "autoShow")
    public Object autoShow(){
        return gitAutoRefreshConfig;
    }
}

注意,以上都是在 client 端做的修改。

之后,重启 client 端,重启后,我们修改 github 上的配置文件内容,并提交更改,再次刷新页面,没有反应。没有问题。

接下来,我们发送 POST 请求到 http://localhost:3302/actuator/refresh 这个接口,用 postman 之类的工具即可,此接口就是用来触发加载新配置的

在 github 中配置 Webhook

这就结束了吗,并没有,总不能每次改了配置后,就用 postman 访问一下 refresh 接口吧,还是不够方便呀。 github 提供了一种 webhook 的方式,当有代码变更的时候,会调用我们设置的地址,来实现我们想达到的目的。

1、进入 github 仓库配置页面,选择 Webhooks ,并点击 add webhook;

image-20200809234405039

2、之后填上回调的地址,也就是上面提到的 actuator/refresh 这个地址,但是必须保证这个地址是可以被 github 访问到的。如果是内网就没办法了。这也仅仅是个演示,一般公司内的项目都会有自己的代码管理工具,例如自建的 gitlab,gitlab 也有 webhook 的功能,这样就可以调用到内网的地址了。

image-20200809234423513

使用 Spring Cloud Bus 来自动刷新多个端

Spring Cloud Bus 将分布式系统的节点与轻量级消息代理链接。这可以用于广播状态更改(例如配置更改)或其他管理指令。一个关键的想法是,Bus 就像一个扩展的 Spring Boot 应用程序的分布式执行器,但也可以用作应用程序之间的通信渠道。

—— Spring Cloud Bus 官方解释

如果只有一个 client 端的话,那我们用 webhook ,设置手动刷新都不算太费事,但是如果端比较多的话呢,一个一个去手动刷新未免有点复杂。这样的话,我们可以借助 Spring Cloud Bus 的广播功能,让 client 端都订阅配置更新事件,当配置更新时,触发其中一个端的更新事件,Spring Cloud Bus 就把此事件广播到其他订阅端,以此来达到批量更新。

服务总线

Bus

通过轻量消息代理连接各个分布的节点。这会用在广播状态的变化(例如配置变化)或者其他的消息指令。Spring bus的一个核心思想是通过分布式的启动器对spring boot应用进行扩展,也可以用来建立一个多个应用之间的通信频道。目前唯一实现的方式是用AMQP消息代理作为通道,同样特性的设置(有些取决于通道的设置)在更多通道的文档中。

配置方式

添加依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>

需要多引入spring-cloud-starter-bus-amqp包,增加对消息总线的支持

配置文件 bootstrap.properties

spring.application.name=spring-cloud-config-client
server.port=8081

spring.cloud.config.name=springcloud-config
spring.cloud.config.profile=dev
spring.cloud.config.label=master
spring.cloud.config.discovery.enabled=true
spring.cloud.config.discovery.serviceId=spring-cloud-config-server

eureka.client.service-url.defaultZone=http://localhost:8761/eureka/

management.endpoints.web.exposure.include=*

## 开启消息跟踪
spring.cloud.bus.trace.enabled=true

spring.rabbitmq.host=127.0.0.1
spring.rabbitmq.port=5672
spring.rabbitmq.username=
spring.rabbitmq.password=

配置文件需要增加RebbitMq的相关配置,这样客户端代码就改造完成了。

SpringCloud Alibaba

Spring Cloud Alibaba 致力于提供微服务开发的一站式解决方案。此项目包含开发分布式应用微服务的必需组件,依托Spring Cloud Alibaba,只需要添加一些注解和少量配置,就可以将Spring Cloud 应用接入阿里微服务解决方案,通过阿里中间件来迅速搭建分布式应用系统。 由于SpringCloud Netflix进入维护期,目前Alibaba在国内有趋势逐渐成为主流

主要组件

nacos:服务注册与发现+配置中心+服务总线

Nacos=Eureka+Config+Bus

前四个字母分别为 Naming 和 Configuration 的前两个字母,最后的s为Service

Nacos提供基于DNS和基于RPC的服务发现,即能被用来支持https/http的服务注册与发现,也支持RPC如dubbo的服务注册与发现。

部署

Nacos支持三种部署模式

  • 单机模式 - 用于测试和单机试用。
  • 集群模式 - 用于生产环境,确保高可用。
  • 多集群模式 - 用于多数据中心场景。

在0.7版本之前,在单机模式时nacos使用嵌入式数据库实现数据的存储,不方便观察数据存储的基本情况。0.7版本增加了支持mysql数据源能力,具体的操作步骤:

  • 1.安装数据库,版本要求:5.6.5+
  • 2.初始化mysql数据库,数据库初始化文件:nacos-mysql.sql
  • 3.修改conf/application.properties文件,增加支持mysql数据源配置(目前只支持mysql),添加mysql数据源的url、用户名和密码。
spring.datasource.platform=mysql

db.num=1
db.url.0=jdbc:mysql://11.162.196.16:3306/nacos_devtest?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
db.user=nacos_devtest
db.password=youdontknow

再以单机模式启动nacos,nacos所有写嵌入式数据库的数据都写到了mysql

集群:

使用mysql数据库

# application.properties配置文件添加如下内容
db.num=2
db.url.0=jdbc:mysql://11.162.196.16:3306/nacos_devtest?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
db.url.1=jdbc:mysql://11.163.152.9:3306/nacos_devtest?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
db.user=nacos_devtest
db.password=nacos
123456
#cluster.conf.example 文件重命名为cluster.conf 
# 删除文件中的注释
# ip 为集群中其他节点的ip ,注意必须包含所有其他节点的ip和端口
10.10.109.214:8848
11.16.128.34:8848
11.16.128.36:8848
123456

微服务里面:

1、引入依赖

service模块中配置Nacos客户端的pom依赖

<!--服务注册-->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>Copy

2、添加服务配置信息

配置application.properties,在客户端微服务中添加注册Nacos服务的配置信息

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

接下来要起一个名字,这样才能知道这个服务在配置中心叫什么

#spring:
  application:
    name: gulimall-couponCopy

3、添加Nacos客户端注解

在客户端微服务启动类中添加注解

@EnableDiscoveryClient   //开启服务注册发现,这个注解可加可不加Copy

4、启动客户端微服务

启动注册中心,启动已注册的微服务,可以在Nacos服务列表中看到被注册的微服务

sentinel:服务容错(限流,熔断,负载)

Seata:分布式事物

alibab cloud sms:短信通讯

alibaba cloud oss:阿里云存储

SpringCloud其他问题

Eureka和ZooKeeper都可以提供服务注册与发现的功能,请说说两个的区别

1.ZooKeeper保证的是CP,Eureka保证的是AP

ZooKeeper在选举期间注册服务瘫痪,虽然服务最终会恢复,但是选举期间不可用的

Eureka各个节点是平等关系,只要有一台Eureka就可以保证服务可用,而查询到的数据并不是最新的

自我保护机制会导致

Eureka不再从注册列表移除因长时间没收到心跳而应该过期的服务

Eureka仍然能够接受新服务的注册和查询请求,但是不会被同步到其他节点(高可用)

当网络稳定时,当前实例新的注册信息会被同步到其他节点中(最终一致性)

Eureka可以很好的应对因网络故障导致部分节点失去联系的情况,而不会像ZooKeeper一样使得整个注册系统瘫痪

2.ZooKeeper有Leader和Follower角色,Eureka各个节点平等

3.ZooKeeper采用过半数存活原则,Eureka采用自我保护机制解决分区问题

4.Eureka本质上是一个工程,而ZooKeeper只是一个进程

Ribbon和Feign的区别?

1.Ribbon和Feign都是调用其他服务的,但方式不同。
2.启动类注解不同,Ribbon是@RibbonClient feign的是@EnableFeignClients
3.服务指定的位置不同,Ribbon是在@RibbonClient注解上声明,Feign则是在定义抽象方法的接口中使用@FeignClient声明。
4.调用方式不同,Ribbon需要自己构建http请求,模拟http请求然后使用RestTemplate发送给其他服务,步骤相当繁琐。Feign需要将调用的方法定义成抽象方法即可。