SpringCloud微服务工具集

SpringCloud微服务工具集

1.什么是微服务

官网: Microservices

In short, the microservice architectural(架构) style is an approach to developing a single application as a suite(系列) of small services, each running in its own process(进程) and communicating with lightweight mechanisms, often an HTTP resource API. These services are built around business(业务) capabilities(单元) and independently(独立) deployable(部署) by fully automated deployment machinery. There is a bare(基于) minimum of centralized(分布式) management(管理) of these services, which may be written in different programming languages and use different data storage technologies. -----[摘自官网]

- a suite of small services            --一系列微小服务
- running in its own process           --运行在自己的进程里
- built around business capabilities   --围绕自己的业务开发
- independently deployable             --独立部署
- bare minimum of centralized management of these services  --基于分布式管理
  • 官方定义:微服务就是由一系列围绕自己业务开发的微小服务构成,他们独立部署运行在自己的进程里,基于分布式的管理

  • 通俗定义:微服务是一种架构,这种架构是将单个的整体应用程序分割成更小的项目关联的独立的服务。一个服务通常实现一组独立的特性或功能,包含自己的业务逻辑和适配器。各个微服务之间的关联通过暴露api来实现。这些独立的微服务不需要部署在同一个虚拟机,同一个系统和同一个应用服务器中。

2.为什么是微服务

传统单体应用

1.优点

  • 单一架构模式在项目初期很小的时候开发方便,测试方便,部署方便,运行良好。

2.缺点

  • 应用随着时间的推进,加入的功能越来越多,最终会变得巨大,一个项目中很有可能数百万行的代码,互相之间繁琐的jar包。

  • 久而久之,开发效率低,代码维护困难

  • 如果想整体应用采用新的技术,新的框架或者语言,那是不可能的。

  • 任意模块的漏洞或者错误都会影响这个应用,降低系统的可靠性

微服务架构应用

1.优点

  • 将服务拆分成多个单一职责的小的服务,进行单独部署,服务之间通过网络进行通信

  • 每个服务应该有自己单独的管理团队,高度自治

  • 服务各自有自己单独的职责,服务之间松耦合,避免因一个模块的问题导致服务崩溃

2.缺点

  • 开发人员要处理分布式系统的复杂性

  • 多服务运维难度,随着服务的增加,运维的压力也在增大

  • 服务治理 和 服务监控难度增加

3.微服务的解决方案

1.Dubbo (阿里系)

  • 初出茅庐:2011年末,阿里巴巴在GitHub上开源了基于Java的分布式服务治理框架Dubbo,之后它成为了国内该类开源项目的佼佼者,许多开发者对其表示青睐。同时,先后有不少公司在实践中基于Dubbo进行分布式系统架构,目前在GitHub上,它的fork、star数均已破万。Dubbo致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案,使得应用可通过高性能RPC实现服务的输出、输入功能和Spring框架无缝集成。Dubbo包含远程通讯、集群容错和自动发现三个核心部分。

  • 停止维护:从2012年10月23日Dubbo 2.5.3发布后,在Dubbo开源将满一周年之际,阿里基本停止了对Dubbo的主要升级。只在之后的2013年和2014年更新过2次对Dubbo 2.4的维护版本,然后停止了所有维护工作。Dubbo对Srping的支持也停留在了Spring 2.5.6版本上。

  • 死而复生:多年漫长的等待,随着微服务的火热兴起,在国内外开发者对阿里不再升级维护Dubbo的吐槽声中,阿里终于开始重新对Dubbo的升级和维护工作。在2017年9月7日,阿里发布了Dubbo的2.5.4版本,距离上一个版本2.5.3发布已经接近快5年时间了。在随后的几个月中,阿里Dubbo开发团队以差不多每月一版本的速度开始快速升级迭代,修补了Dubbo老版本多年来存在的诸多bug,并对Spring等组件的支持进行了全面升级。

  • 2018年1月8日,Dubbo创始人之一梁飞在Dubbo交流群里透露了Dubbo 3.0正在动工的消息。Dubbo 3.0内核与Dubbo 2.0完全不同,但兼容Dubbo 2.0。Dubbo 3.0将以Streaming为内核,不再是Dubbo 时代的RPC,但是RPC会在Dubbo 3.0中变成远程Streaming对接的一种可选形态。从Dubbo新版本的路线规划上可以看出,新版本的Dubbo在原有服务治理的功能基础上,将全面拥抱微服务解决方案。

  • 结论:当前由于RPC协议、注册中心元数据不匹配等问题,在面临微服务基础框架选型时Dubbo与Spring Cloud是只能二选一,这也是为什么大家总是拿Dubbo和Spring Cloud做对比的原因之一。Dubbo之后会积极寻求适配到Spring Cloud生态,比如作为Spring Cloud的二进制通信方案来发挥Dubbo的性能优势,或者Dubbo通过模块化以及对http的支持适配到Spring Cloud。

2.Spring Cloud:

  • Spring Cloud NetFlix

    基于美国Netflix公司开源的组件进行封装,提供了微服务一栈式的解决方案。

  • Spring Cloud alibaba

    在Spring cloud netflix基础上封装了阿里巴巴的微服务解决方案。

  • Spring Cloud Spring

    目前spring官方趋势正在逐渐吸收Netflix组件的精华,并在此基础进行二次封装优化,打造spring专有的解决方案

4.什么是SpringCloud

官网: Spring Cloud

Spring Cloud provides tools for developers to quickly build some of the common patterns in distributed systems (e.g. configuration management,service discovery, circuit breakers, intelligent routing, micro-proxy, control bus). Coordination of distributed systems leads to boiler plate patterns, and using Spring Cloud developers can quickly stand up services and applications that implement those patterns. -------[摘自官网]

通俗理解

  • springcloud是一个含概多个子项目的开发工具集,集合了众多的开源框架,他利用了Spring Boot开发的便利性实现了很多功能,如服务注册,服务注册发现,负载均衡等.SpringCloud在整合过程中主要是针对Netflix(耐非)开源组件的封装.SpringCloud的出现真正的简化了分布式架构的开发。NetFlix 是美国的一个在线视频网站,微服务业的翘楚,他是公认的大规模生产级微服务的杰出实践者,NetFlix的开源组件已经在他大规模分布式微服务环境中经过多年的生产实战验证,因此Spring Cloud中很多组件都是基于NetFlix

核心架构及其组件

核心组件说明

  • eurekaserver、consul、nacos 服务注册中心组件

  • rabbion & openfeign 服务负载均衡 和 服务调用组件

  • hystrix & hystrix dashboard 服务断路器 和 服务监控组件

  • zuul、gateway 服务网关组件

  • config 统一配置中心组件

  • bus 消息总线组件 ......

5.环境搭建

版本命名

springcloud是一个由众多独立子项目组成的大型综合项目,原则每个子项目上有不同的发布节奏,都维护自己发布版本号。为了更好的管理springcloud的版本,通过一个资源清单BOM(Bill of Materials),为避免与子项目的发布号混淆,所以没有采用版本号的方式,而是通过命名的方式。这些名字是按字母顺序排列的。如伦敦地铁站的名称(“天使”是第一个版本,“布里斯顿”是第二个版本,"卡姆登"是第三个版本)。当单个项目的点发布累积到一个临界量,或者其中一个项目中有一个关键缺陷需要每个人都可以使用时,发布序列将推出名称以“.SRX”结尾的“服务发布”,其中“X”是一个数字。

2.伦敦地铁站名称 [了解]

  • Angel、Brixton、Camden、Dalston、Edgware、Finchley、Greenwich、Hoxton

版本选择

环境搭建

  • springboot 2.2.5.RELEASE

  • springcloud Hoxton.SR6

  • java8

  • maven 3.3.5

  • idea 2020

1.创建springboot项目 指定版本为 2.2.5.RELEASE版本

<!--    继承springboot的父工程-->
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.2.5.RELEASE</version>
</parent>
​
<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
    </plugins>
</build>

2.引入springcloud的版本管理

<!--    统一维护依赖的版本-->
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <java.version>1.8</java.version>
        <spring-cloud.version>Hoxton.SR6</spring-cloud.version>
    </properties>
    <!--全局管理springcloud版本,并不会引入具体依赖-->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>      <!-- 其它组件小版本号的维护-->
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

3.完成上述操作springboot与springcloud环境搭建完成,接下来就是使用到具体的springcloud组件,在项目中引入具体的组件即可

6.服务注册中心

什么是服务注册中心

所谓服务注册中心就是在整个的微服务架构中单独提出一个服务,这个服务不完成系统的任何的业务功能,仅仅用来完成对整个微服务系统的服务注册和服务发现,以及对服务健康状态的监控和管理功能。

1.服务注册中心

  • 可以对所有的微服务的信息进行存储,如微服务的名称、IP、端口等

  • 可以在进行服务调用时通过服务发现查询可用的微服务列表及网络地址进行服务调用

  • 可以对所有的微服务进行心跳检测,如发现某实例长时间无法访问,就会从服务注册表移除该实例

2.常用的注册中心

springcloud支持的多种注册中心Eureka、Consul(GO)、Zookeeper(java)、以及阿里巴巴推出Nacos(java)。这些注册中心在本质上都是用来管理服务的注册和发现以及服务状态的检查的。

Eureka注册中心

官网:https://github.com/Netflix/eureka/wiki

简介

Eureka是Netflix开发的服务发现框架,本身是一个基于REST的服务。SpringCloud将它集成在其子项目spring-cloud-netflix中,以实现SpringCloud的服务注册和发现功能。Eureka包含两个组件:

  • Eureka Server

  • Eureka Client

开发Eureka Server

1.创建项目并引入eureka server依赖

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!--引入 eureka server-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
    </dependency>
</dependencies>

2.编写配置application.yml

server:
  port: 8761 # eureka 默认的端口号
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:8761/eureka  #指定服务注册中心的地址
#指定服务注册中心的名字
spring:
  application:
    name: EUREKASERVER #服务名称不要使用下划线  服务名称不区分大小写 推荐服务名大写

3.开启EurekaServer,入口类加入注解

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

4.访问Eureka的服务注册页面

http://localhost:8761

5.为什么项目启动控制台报错?

原因分析:

eureka组件包含 eurekaserver 和 eurekaclient。server是一个服务注册中心,用来接受客户端的注册。client的特性会让当前启动的服务把自己作为eureka的客户端进行服务中心的注册,当项目启动时服务注册中心还没有创建好,所以找不到服务的客户端组件就直接报错了,当服务注册中心启动成功后,就不再报错啦!

解决方案:

eureka.client.register-with-eureka=false    #不再将自己作为客户端进行注册  
eureka.client.fetch-registry=false      # 不获取注册信息

再次启动,控制器也不再报错

开发Eureka Client

1.创建项目并引入eureka client依赖

<!--引入eureka client-->
<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

2.编写配置application.yml

server.port=8888        #服务端口号                                          
spring.application.name=eurekaclient8888    #服务名称唯一标识
eureka.client.service-url.defaultZone=http://localhost:8761/eureka #eureka注册中心地址

3.开启eureka客户端并加入注解

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

4.启动服务注册中心,然后启动eureka客户端服务

5.查看eureka server的服务注册情况

Eureka自我保护机制

服务频繁启动时 EurekaServer出现错误

  • EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY'RE NOT. RENEWALS ARE LESSER THAN THRESHOLD AND HENCE THE INSTANCES ARE NOT BEING EXPIRED JUST TO BE SAFE.

自我保护机制

官网地址: https://github.com/Netflix/eureka/wiki/Server-Self-Preservation-Mode

默认情况下,如果Eureka Server在一定时间内(默认90秒)没有接收到某个微服务实例的心跳,Eureka Server将会移除该实例。但是当网络分区故障发生时,微服务与Eureka Server之间无法正常通信,而微服务本身是正常运行的,此时不应该移除这个微服务,所以引入了自我保护机制。

Eureka Server在运行期间会去统计心跳失败比例在 15 分钟之内是否低于 85%,如果低于 85%,Eureka Server 会将这些实例保护起来,让这些实例不会过期。这种设计的哲学原理就是"宁可信其有不可信其无!"。自我保护模式正是一种针对网络异常波动的安全保护措施,使用自我保护模式能使Eureka集群更加的健壮、稳定的运行。

在Eureka server端关闭自我保护机制

eureka.server.enable-self-preservation=false  #关闭自我保护
eureka.server.eviction-interval-timer-in-ms=3000 #超时3s自动清除  默认60*1000 1min钟清除
----------------------------yml风格------------------------------------------
eureka:
  server:
    enable-self-preservation: false  # 关闭自我保护机制
    eviction-interval-timer-in-ms: 3000 # 超时移除时间

微服务客户端修改减短服务心跳的时间

eureka.instance.lease-expiration-duration-in-seconds=10 #用来修改eureka server默认接受心跳的最大时间 默认是90s
eureka.instance.lease-renewal-interval-in-seconds=5 #指定客户端多久向eureka server发送一次心跳 默认是30s
--------------------------------yml风格--------------------------------------
eureka:
  instance:
    lease-expiration-duration-in-seconds: 10
    lease-renewal-interval-in-seconds: 5

尽管如此关闭自我保护机制还是会出现警告

官方不建议关闭Eureka自我保护机制

Eureka集群的搭建

1.按照之前创建EurekaServer的方式创建多个服务器端,修改端口号和注册中心地址

2.客户端集群也可采用之前创建客户端的方式创建多个客户端,修改端口号和注册中心地址

3.不采用以上的两种形式也可以利用IDEA工具进行集群的快速搭建,操作方式如下:

修改端口号:-Dserver.port=9090

复制完成后,启动项目即可

eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:8788/eureka,http://127.0.0.1:8789/eureka
      
#客户端
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8787/eureka,http://localhost:8788/eureka,http://localhost:8789/eureka
​

Consul注册中心

官网:Consul by HashiCorp

consul是一个可以提供服务发现,健康检查,多数据中心,Key/Value存储等功能的分布式服务框架,用于实现分布式系统的服务发现与配置。与其他分布式服务注册与发现的方案,使用起来也较为简单。Consul用Golang实现,因此具有天然可移植性(支持Linux、Windows和Mac OS X);安装包仅包含一个可执行文件,方便部署。

1.下载consul

2.安装consul

3.根据解压缩目录配置环境变量

4.查看consul环境变量是否配置成功,执行命令出现如下信息代表成功

5.访问consul的web服务端口

http://localhost:8500

指定数据中心启动 consul agent -dev -datacenter mosin

6.开发consul 客户端即微服务

  • 1.创建项目并引入consul客户端依赖

 <!--引入consul依赖-->
<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
  • 编写yml配置

server.port=8889
spring.application.name=consulclient8889
spring.cloud.consul.host=localhost  #注册consul服务的主机                  
spring.cloud.consul.port=8500       #注册consul服务的端口号                  
#指定注册的服务名称 默认就是应用名
spring.cloud.consul.discovery.service-name=${spring.application.name} 
  • 启动服务查看consul界面服务信息

  • consul 开启健康监控检查

开启consul健康监控

默认情况consul监控健康是开启的,但是必须依赖健康监控依赖才能正确监控健康状态所以直接启动会显示错误,引入健康监控依赖之后服务正常

<!-- 这个包是用做健康度监控的-->
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

关闭consul的健康检查(不推荐)

spring.cloud.consul.discovery.register-health-check=false

不同注册中心区别

1.CAP定理

CAP定理:CAP定理又称CAP原则,指的是在一个分布式系统中,一致性(Consistency)、可用性(Availability)、分区容错性(Partition tolerance)。CAP 原则指的是,这三个要素最多只能同时实现两点,不可能三者兼顾。

一致性(C):
在分布式系统中的所有数据备份,在同一时刻是否同样的值。(等同于所有节点访问同一份最新的数据副本)
可用性(A):
在集群中一部分节点故障后,集群整体是否还能响应客户端的读写请求。(对数据更新具备高可用性)
分区容忍性(P):
就是高可用性,一个节点崩了,并不影响其它的节点(100个节点,挂了几个,不影响服务,越多机器越好)

2.Eureka特点

  • Eureka中没有使用任何的数据强一致性算法保证不同集群间的Server的数据一致,仅通过数据拷贝的方式争取注册中心数据的最终一致性,虽然放弃数据强一致性但是换来了Server的可用性,降低了注册的代价,提高了集群运行的健壮性。

3.Consul特点

  • 基于Raft算法,Consul提供强一致性的注册中心服务,但是由于Leader节点承担了所有的处理工作,势必加大了注册和发现的代价,降低了服务的可用性。通过Gossip协议,Consul可以很好地监控Consul集群的运行,同时可以方便通知各类事件,如Leader选择发生、Server地址变更等。

4.zookeeper特点

  • 基于Zab协议,Zookeeper可以用于构建具备数据强一致性的服务注册与发现中心,而与此相对地牺牲了服务的可用性和提高了注册需要的时间。

7. 服务间通信方式

在整个微服务架构中,服务间的服务改如何调用,有哪些调用方式?

在springcloud中服务间调用方式主要是使用 http restful方式进行服务间调用。

1.基于RestTemplate的服务调用

spring框架提供的RestTemplate类可用于在应用中调用rest服务,它简化了与http服务的通信方式,统一了RESTful的标准,封装了http链接, 我们只需要传入url及返回值类型即可。相较于之前常用的HttpClient,RestTemplate是一种更优雅的调用RESTful服务的方式。

创建用户服务的springboot工程

引入依赖

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--        引入consul客户端依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-consul-discovery</artifactId>
        </dependency>
        <!--        引入健康检查依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
    </dependencies>

编写application.yml文件

server:
  port: 8888  #配置服务端口
spring:
  application:
    name: USERS  #配置服务名
  cloud:
    consul:
      port: 8500  #注册中心端口
      host: localhost #注册中心地址

编写启动类,添加注解

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

创建订单服务的springboot工程

引入依赖(参照用户服务)

编写application.yml文件

server:
  port: 8889  #配置服务端口
spring:
  application:
    name: ORDERS  #配置服务名
  cloud:
    consul:
      port: 8500  #注册中心端口
      host: localhost #注册中心地址

编写启动类,添加注解

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

编写用户服务和订单服务的控制层,并实现调用

@Controller
public class UserController {
    private Logger logger = LoggerFactory.getLogger(getClass());
    @GetMapping("/user")
    @ResponseBody
    public String invokeOrder(){
        logger.info("用户服务被调用!");
        // 创建发送http请求的 RestTemplate 对象
        RestTemplate restTemplate = new RestTemplate();
        String rest = restTemplate.getForObject("http://localhost:8889/order", String.class);
        logger.info("订单服务调用成功,返回结果"+rest);
        return " Invoke UsersService ok "+rest;
    }
​
}
​
@Controller
public class OrderController {
    private  Logger logger = LoggerFactory.getLogger(getClass());
    @GetMapping("/order")
    @ResponseBody
    public String OrderTest(){
        logger.info("订单服务被调用!");
        return " invoke  OrderService ok";
    }
}

问题:

1.以上的通信方式已经将访问的地址写成固定的值,无法实现负载的均衡

2.提供接口的服务发生改变,不利于服务的维护

解决问题:负载均衡

1.自定义负载均衡

//实现调用订单接口的随机策略 实现负载均衡
public String getHost(){
    ArrayList<String> hosts = new ArrayList<>();
    hosts.add("localhost:8889");
    hosts.add("localhost:9090");
    return hosts.get(new Random().nextInt(hosts.size()));
}

问题:

  • 1.无法实现服务的健康检查

  • 2.均衡的策略比较单一 (随机策略)

2.基于Ribbon的服务调用

  • 官方网址: https://github.com/Netflix/ribbon

  • Spring Cloud Ribbon是一个基于HTTP和TCP的客户端负载均衡工具,它基于Netflix Ribbon实现。通过Spring Cloud的封装,可以让我们轻松地将面向服务的REST模版请求自动转换成客户端负载均衡的服务调用。

引入Ribbon的依赖

<!--引入ribbon依赖-->
<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>

编写application.yml

server:
  port: 8082
spring:
  application:
    name: USERSCLIENT  #服务名称
  cloud:
    consul:
      host: localhost  # 服务注册的地址
      discovery:
        service-name: USERSCLIENT  # 服务注册的名字
      port: 8500

改写用户服务和订单服务的控制层,并实现调用

@Controller
public class UsersController {
    @Autowired
    private DiscoveryClient discoveryClient; //直接注入
    @Autowired
    private LoadBalancerClient loadBalancerClient; //直接注入
    @Autowired
    private  RestTemplate restTemplate;  //配置后注入
​
    @GetMapping("/user")
    @ResponseBody
    public String invokeOrders(){
        RestTemplate restTemplate = new RestTemplate();
        String result = restTemplate.getForObject("http://localhost:8091/order", String.class);
        System.out.println(result);
        return "users service ok";
    }
​
    @GetMapping("/user2")
    @ResponseBody
    public String invokeOrders2(){
​
        List<ServiceInstance> ordersclient = discoveryClient.getInstances("ORDERSCLIENT");
        ServiceInstance serviceInstance = ordersclient.get(new Random().nextInt(ordersclient.size()));
        URI uri = serviceInstance.getUri();
        System.out.println("uri = " + uri);
        RestTemplate restTemplate = new RestTemplate();
        String result = restTemplate.getForObject(uri+"/order", String.class);
        System.out.println(result);
        return "users service ok";
    }
​
    @GetMapping("/user3")
    @ResponseBody
    public String invokeOrders3(){
        ServiceInstance ordersclient = loadBalancerClient.choose("ORDERSCLIENT");
        URI uri = ordersclient.getUri();
        System.out.println("uri = " + uri);
        return "users service ok";
    }
​
    @GetMapping("/user4")
    @ResponseBody
    public String invokeOrders4(){
        String result = restTemplate.getForObject("http://ORDERSCLIENT/order", String.class);
        return "users service ok";
    }
}

使用Ribbon注解实现负载均衡前需要使用配置类配置RestTemplate

@Configuration
public class BeansConfig {
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return  new RestTemplate();
    }
}

Ribbon的负载均衡策略

1.ribbon负载均衡算法

  • RoundRobinRule 轮循策略 按顺序循环选择 Server

  • RandomRule 随机策略 随机选择 Server

  • AvailabilityFilteringRule 可用过滤策略

`会先过滤由于多次访问故障而处于断路器跳闸状态的服务,还有并发的连接数量超过阈值的服务,然后对剩余的服务列表按照轮询策略进行访问
  • WeightedResponseTimeRule 响应时间加权策略

    根据平均响应的时间计算所有服务的权重,响应时间越快服务权重越大被选中的概率越高,刚启动时如果统计信息不足,则使用RoundRobinRule策略,等统计信息足够会切换到

  • RetryRule 重试策略

    先按照RoundRobinRule的策略获取服务,如果获取失败则在制定时间内进行重试,获取可用的服务。

  • BestAviableRule 最低并发策略

    会先过滤掉由于多次访问故障而处于断路器跳闸状态的服务,然后选择一个并发量最小的服务

设置负载均衡策略(服务调用端)

#设置负载均衡策略
ORDERSCLIENT:  # 服务的名称
  ribbon:
   NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

8.OpenFeign组件的使用

思考: 使用RestTemplate+ribbon已经可以完成对端的调用,为什么还要使用feign?

String restTemplateForObject = restTemplate.getForObject("http://服务名/url?参数" + name, String.class);

存在问题:

  • 1.每次调用服务都需要写这些代码,存在大量的代码冗余

  • 2.服务地址如果修改,维护成本增高

  • 3.使用时不够灵活

官网:Spring Cloud OpenFeign

Feign是一个声明式的伪Http客户端,它使得服务间的通信变得更简单。使用Feign,只需要创建一个接口并添加注解。同时可以完成数据的自动转换,它具有可插拔的注解特性(可以使用springmvc的注解),可使用Feign 注解和JAX-RS注解。Feign支持可插拔的编码器和解码器。Feign默认集成了Ribbon,默认实现了负载均衡的效果并且springcloud为feign添加了springmvc注解的支持

1.创建商品服务和商品类目服务(注册Consul注册中心)

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients //OpenFeign注解
public class ProductsApplication {
​
    public static void main(String[] args) {
        SpringApplication.run(ProductsApplication.class, args);
    }
}
​
@SpringBootApplication
@EnableDiscoveryClient
public class CategoryApplication {
​
    public static void main(String[] args) {
        SpringApplication.run(CategoryApplication.class, args);
    }
}

2.添加OpenFeign依赖(消费者端)

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

3.添加启动类注解

@EnableFeignClients

4.在消费端编写OpenFeign客户端接口

@FeignClient("CATEGORY")
public interface CategoryClient {
    @GetMapping("/category") //请求方式 和请求的路径和服务提供者保持一致
    String test01();
}

5.消费者调用

@Controller
public class ProductsController {
    @Autowired
    private CategoryClient categoryClient; //注入接口
    @RequestMapping("/product")
    @ResponseBody
    public String testProduct(){
        String s = categoryClient.test01();//调用接口中的方法
        return "Products Ok ::"+s;
    }
}

服务间参数传递和响应处理

  • 1.参数的传递(零散)

    1.普通传参

    //客户端接口方法
    @GetMapping("/cat2")
    String test02(@RequestParam("id") Integer id,@RequestParam("name")String name);

    2.Restful传参

    //客户端接口方法
    @GetMapping("/cat2/{id}/{name}")
    String test02(@PathVariable("id") Integer id, @PathVariab le("name") String name);
  • 2.参数的传递(对象)

    //客户端接口方法
    @PostMapping("/p4")
    String test04(@RequestBody User user);
    
    // 服务的提供方 controller
    @PostMapping("/p4")
    @ResponseBody
    public String test04(@RequestBody User user){
        logger.info(user.toString());
        return  "Products ok";
    }
  • 3.参数的传递(数组)

//数组
@GetMapping("/p5")
String test05(@RequestParam("ids")String[] ids);

//服务的提供方
@GetMapping("/p5")
@ResponseBody
public String test05(String[] ids){
    for (String id : ids) {
        System.out.println(id);
    }
    return  "test05 ok";
}

服务间响应处理

@GetMapping("/cat6")
@ResponseBody //响应单个数据
public Product test05(Integer id){
    Product product = productsClient.test06(id);
    return product;
}

@GetMapping("/cat7")
@ResponseBody  //响应集合
public List<Product> test06(Integer id){
    return productsClient.test07(id);
}

服务调用超时处理(超出1秒调用超时)

修改超时时间

feign:
  client:
    config:
      PRODUCTS:
         connectTimeout: 5000   #连接超时时间
        readTimeout: 5000   #读取超时时间
        
        
 #全局超时时间控制
 feign:
  client:
    config:
     default:
         connectTimeout:: 5000   #连接超时时间
         readTimeout: 5000   #读取超时时间
 

9.Hystrix组件使用

In a distributed environment, inevitably some of the many service dependencies will fail. Hystrix is a library that helps you control the interactions between these distributed services by adding latency tolerance and fault tolerance logic. Hystrix does this by isolating points of access between the services, stopping cascading failures across them, and providing fallback options, all of which improve your system’s overall resiliency. --[摘自官方]

官网:https://github.com/Netflix/Hystrix

  • 译: 在分布式环境中,许多服务依赖项不可避免地会失败。Hystrix是一个库,它通过添加延迟容忍和容错逻辑来帮助您控制这些分布式服务之间的交互。Hystrix通过隔离服务之间的访问点、停止它们之间的级联故障以及提供后备选项来实现这一点,所有这些都可以提高系统的整体弹性。

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

作用

  • hystrix 用来保护微服务系统 实现 服务降级 服务熔断

名词解析:

1.服务雪崩

在微服务之间进行服务调用是由于某一个服务故障,导致级联服务故障的现象,称为雪崩效应。雪崩效应描述的是提供方不可用,导致消费方不可用并将不可用逐渐放大的过程

如果此时,Service A的流量波动很大,流量经常会突然性增加!那么在这种情况下,就算Service A能扛得住请求,Service B和Service C未必能扛得住这突发的请求。此时,如果Service C因为抗不住请求,变得不可用。那么Service B的请求也会阻塞,慢慢耗尽Service B的线程资源,Service B就会变得不可用。紧接着,Service A也会不可用,这一过程如下图所示

2.服务熔断

“熔断器”本身是一种开关装置,当某个服务单元发生故障之后,通过断路器(hystrix)的故障监控,某个异常条件被触发,直接熔断整个服务。向调用方法返回一个符合预期的、可处理的备选响应(FallBack),而不是长时间的等待或者抛出调用方法无法处理的异常,就保证了服务调用方的线程不会被长时间占用,避免故障在分布式系统中蔓延,乃至雪崩。如果目标服务情况好转则恢复调用。服务熔断是解决服务雪崩的重要手段

3.服务降级

服务压力剧增的时候根据当前的业务情况及流量对一些服务和页面有策略的降级,以此缓解服务器的压力,以保证核心任务的进行。同时保证部分甚至大部分任务客户能得到正确的响应。也就是当前的请求处理不了了或者出错了,给一个默认的返回。

  • 服务降级: 关闭微服务系统中某些边缘服务 保证系统核心服务正常运行

  • 12 淘宝 京东

  • 删除订单 --- 关闭订单 确认收货 ----> 服务繁忙,!!!

降级和熔断总结

1.共同点

  • 目的很一致,都是从可用性可靠性着想,为防止系统的整体缓慢甚至崩溃,采用的技术手段;

  • 最终表现类似,对于两者来说,最终让用户体验到的是某些功能暂时不可达或不可用;

  • 粒度一般都是服务级别,当然,业界也有不少更细粒度的做法,比如做到数据持久层(允许查询,不允许增删改);

  • 自治性要求很高,熔断模式一般都是服务基于策略的自动触发,降级虽说可人工干预,但在微服务架构下,完全靠人显然不可能,开关预置、配置中心都是必要手段;sentinel

2.异同点

  • 触发原因不太一样,服务熔断一般是某个服务(下游服务)故障引起,而服务降级一般是从整体负荷考虑;

  • 管理目标的层次不太一样,熔断其实是一个框架级的处理,每个微服务都需要(无层级之分),而降级一般需要对业务有层级之分(比如降级一般是从最外围服务边缘服务开始)

3.总结

  • 熔断必会触发降级,所以熔断也是降级一种,区别在于熔断是对调用链路的保护,而降级是对系统过载的一种保护处理

服务熔断的实现

1.创建一个单独的springboot工程,演示Hystrix

2.引入consul注册中心的相关依赖

3.引入Hystrix依赖

<!--引入hystrix-->
<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>

4.编写启动类 添加注解

@SpringBootApplication
@EnableDiscoveryClient
@EnableCircuitBreaker //开启hystrix熔断服务
public class HysTrixApplication {
    public static void main(String[] args) {
        SpringApplication.run(HysTrixApplication.class, args);
    }
}

5.编写控制器 添加注解

@Controller
public class HystrixController {

    @RequestMapping("/h1")
    @ResponseBody
    @HystrixCommand(fallbackMethod = "Test01fallbackMethod")
    public String test01(Integer id){
        if(id<0){
            throw  new  RuntimeException("无效id!");
        }
        return "hystrix ok";
    }

    @ResponseBody
    public String Test01fallbackMethod(Integer id){
       return "商品过于火爆,服务被熔断,请稍后再试!"+id;
    }
}

5.总结

  • 从上面演示过程中会发现如果触发一定条件断路器会自动打开,过了一点时间正常之后又会关闭。那么断路器打开条件是什么呢?

6.断路器打开条件

1、 当满足一定的阀值的时候(默认10秒内超过20个请求失败)

2、 当失败率达到一定的时候(默认10秒内超过50%的请求失败)

3、 到达以上阀值,断路器将会开启

4、 当开启的时候,所有请求都不会进行转发

5、 一段时间之后(默认是5秒),这个时候断路器是半开状态,会让其中一个请求进行转发。如果成功,断路器会关闭,若失败,继续开启。重复4和5。

默认的服务FallBack处理方法

  • 如果为每一个服务方法开发一个降级,对于我们来说,可能会出现大量的代码的冗余,不利于维护,这个时候就需要加入默认服务降级处理方法

服务降级的实现

服务降级: 站在系统整体负荷角度 实现: 关闭系统中某些边缘服务 保证系统核心服务运行 Emps 核心服务 Depts 边缘服务

1.客户端openfeign + hystrix实现服务降级实现

  • 引入hystrix依赖

  • 配置文件开启feign支持hystrix

  • 在feign客户端调用加入fallback指定降级处理

  • 开发降级处理方法

2.开启openfeign支持服务降级

feign.hystrix.enabled=true #开启openfeign支持降级

3.在openfeign客户端中加如Hystrix

@FeignClient(value = "HYSTRIXCLIENT",fallback = HysClientFallback.class)
public interface HysClient {
    @GetMapping("/h2")
    String test02(@RequestParam Integer id);
}

4.开发fallback处理类

@Component
public class HysClientFallback implements HysClient{
    @Override
    public String test02(Integer id) {
        return "服务器繁忙,请稍后再试!"+id;
    }
}

10.Gateway组件使用

什么是服务网关

网关统一服务入口,可方便实现对平台众多服务接口进行管控,对访问服务的身份认证、防报文重放与防数据篡改、功能调用的业务鉴权、响应数据的脱敏、流量与并发控制,甚至基于API调用的计量或者计费等等。

  • 网关 = 路由转发 + 过滤器+负载均衡 路由转发:接收一切外界请求,转发到后端的微服务上去

  • 网关组件在微服务中架构

zuul 1.x 2.x(netflix 组件)

Zuul is the front door for all requests from devices and web sites to the backend of the Netflix streaming application. As an edge service application, Zuul is built to enable dynamic routing, monitoring, resiliency and security.

zul是从设备和网站到Netflix流媒体应用程序后端的所有请求的前门。作为一个边缘服务应用程序,zul被构建为支持动态路由、监视、弹性和安全性

zuul版本说明

  • 目前zuul组件已经从1.0更新到2.0,但是作为springcloud官方不再推荐使用zuul2.0,但是依然支持zuul2

gateway (spring)

This project provides a library for building an API Gateway on top of Spring MVC. Spring Cloud Gateway aims to provide a simple, yet effective way to route to APIs and provide cross cutting concerns to them such as: security, monitoring/metrics, and resiliency.

- 这个项目提供了一个在springmvc之上构建API网关的库。springcloudgateway旨在提供一种简单而有效的方法来路由到api,并为api提供横切关注点,比如:安全性、监控/度量和弹性。
# 1.特性
- 基于springboot2.x 和 spring webFlux 和 Reactor 构建 响应式异步非阻塞IO模型
- 动态路由
- 请求过滤

开发网关动态路由

网关配置有两种方式

  • 一种是快捷方式(Java代码编写网关)

  • 一种是完全展开方式(配置文件方式)[推荐]

1.创建项目引入网关依赖

<!--引入gateway网关依赖-->
<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>

快捷方式配置路由

编写网关配置

server:
  port: 9999
spring:
  application:
    name: GATEWAY
  cloud:
    consul:
      host: localhost
      port: 8500
    gateway:
      routes:
        - id: category_router #路由唯一标识
          uri: http://localhost:9090 #路由转发地址
          predicates:
            - Path=/cat1

        - id: priducts_router #路由唯一标识
          uri: http://localhost:8787 #路由转发地址
          predicates:
            - Path=/p1    #/p1 ,/p2 ,/p3 多个路径映射
            
 ---------------------------------------------------------------------------
         - id: priducts_router #路由唯一标识
           uri: http://localhost:8787 #路由转发地址
           predicates:
             - Path=/p/**

启动gateway网关项目

  • 直接启动报错:

在启动日志中发现,gateway为了效率使用webflux进行异步非阻塞模型的实现,因此和原来的web包冲突,去掉原来的web即可

再次启动成功启动

测试网关路由转发

java方式配置路由

官网:Spring Cloud Gateway

@Configuration
public class GateWayConfig {
    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
        return  builder.routes()
                .route("category_router",r->r.path("/cat1")
                        .uri("http://localhost:9090"))
                .route("product_router",r->r.path("/p1")
                        .uri("http://localhost:8787"))
                .build();
    }
}

查看网关路由规则列表

gateway提供路由访问规则列表的web界面,但是默认是关闭的,如果想要查看服务路由规则可以在配置文件中开启

management:
  endpoints:
    web:
      exposure:
        include: "*"   #开启所有web端点暴露
- 访问路由管理列表地址
- http://localhost:8989/actuator/gateway/routes

配置路由服务负载均衡

spring:
  application:
    name: gateway
  cloud:
    consul:
      host: localhost
      port: 8500
    gateway:
      routes:
         - id: priducts_router #路由唯一标识
          uri: lb://PRODUCTS
          predicates:
            - Path=/p/**    
      discovery:
        locator:
          enabled: true 			#开启根据服务名动态获取路由

常用路由predicate(断言,验证)

Gateway支持多种方式的predicate

- After=2023-01-06T11:32:53.698+08:00[Asia/Shanghai]`指定日期之后的请求进行路由

- Before=2021-12-25T23:29:38.905+08:00[Asia/Shanghai]指定日期之前的请求进行路由

- Between=2021-12-25T23:29:38.905+08:00[Asia/Shanghai], 2021-12-27T23:29:38.905+08:00[Asia/Shanghai]
- Cookie=username,mosin					    基于指定cookie的请求进行路由
- Cookie=username,[A-Za-z0-9]+				基于指定cookie的请求进行路由	
curl http://localhost:8989/user/findAll --cookie "username=zhangsna"
- Header=X-Request-Id, \d ``基于请求头中的指定属性的正则匹配路由(这里全是整数)
curl http://localhost:8989/user/findAll -H "X-Request-Id:11"
- Method=GET,POST		 		基于指定的请求方式请求进行路由

常用的Filter以及自定义filter

Route filters allow the modification of the incoming HTTP request or outgoing HTTP response in some manner. Route filters are scoped to a particular route. Spring Cloud Gateway includes many built-in GatewayFilter Factories.

官网: Spring Cloud Gateway

  • 路由过滤器允许以某种方式修改传入的HTTP请求或传出的HTTP响应。路由筛选器的作用域是特定路由。springcloudgateway包括许多内置的GatewayFilter工厂。

  • 作用

    当我们有很多个服务时,比如下图中的user-service、order-service、product-service等服务,客户端请求各个服务的Api时,每个服务都需要做相同的事情,比如鉴权、限流、日志输出等。

使用内置过滤器

 filters:
    - AddRequestHeader=user_name, mosin				增加请求头的filter`
    - AddRequestParameter=color, blue				    增加请求参数的filterr`
    - AddResponseHeader=X-Response-Red, AAA				增加响应头filter`
    - PrefixPath=/emp									增加前缀的filter`
    - StripPrefix=2										去掉前缀的filter`

11.Config组件使用

什么是Config

config(配置)又称为 统一配置中心顾名思义,就是将配置统一管理,配置统一管理的好处是在日后大规模集群部署服务应用时相同的服务配置一致,日后再修改配置只需要统一修改全部同步,不需要一个一个服务手动维护。

统一配置中心组件流程图

Config Server 开发

1.引入依赖

<!--引入统一配置中心-->
<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-config-server</artifactId>
</dependency>

2.开启统一配置中心服务

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

3.修改配置文件

server:
  port: 8848
spring:
  application:
    name: CONFIGSERVER
  cloud:
    consul:
      port: 8500
      host: 127.0.0.1

4.直接启动服务报错

没有指定远程仓库的相关配置

5.创建远程仓库

6.复制仓库地址

7.在统一配置中心服务中修改配置文件指向远程仓库地址

spring:
  cloud:
    config:
          server:
            git:
              uri: https://gitee.com/classmeng/config.git # 配置远程仓库的地址
             # username:
             # password:   私有仓库需要设置用户名和密码
            default-label: master  #配置分支

8.再次启动统一配置中心

9.拉取远端配置 三种方式

Config Client 开发

1.引入依赖

<!--引入config client-->
<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-config</artifactId>
</dependency>

2.修改配置文件

spring:
  cloud:
    config:
      discovery:
        enabled: true   #开启根据服务id 获取configServer ip地址
        service-id: CONFIGSERVER
      label: master   #分支
      name: configclient  #文件的名字
      profile: dev   #配置环境  哪个文件生效
    consul:
      port: 8500
      host: localhost

3.启动报错

原因分析

项目中目前使用的是application.yml启动项目,使用这个配置文件在springboot项目启动过程中不会等待远程配置拉取,直接根据配置文件中内容启动,因此当需要注册中心,服务端口等信息时,远程配置还没有拉取到,所以直接报错

解决方案

应该在项目启动时先等待拉取远程配置,拉取远程配置成功之后再根据远程配置信息启动即可,为了完成上述要求springboot官方提供了一种解决方案,就是在使用统一配置中心时应该将微服务的配置文件名修改为bootstrap.(properties|yml),bootstrap.properties作为配置启动项目时,会优先拉取远程配置,远程配置拉取成功之后根据远程配置启动当前应用

image-20200722103823678

再次启动服务

image-20200722103913142

image-20200722104031932

手动配置刷新

在生产环境中,微服务可能非常多,每次修改完远端配置之后,不可能对所有服务进行重新启动,这个时候需要让修改配置的服务能够刷新远端修改之后的配置,从而不要每次重启服务才能生效,进一步提高微服务系统的维护效率。在springcloud中也为我们提供了手动刷新配置和自动刷新配置两种策略,这里我们先使用手动配置文件刷新。

在config client端加入刷新暴露端点

management.endpoints.web.exposure.include=*          #开启所有web端点暴露
-----------------------------------yml--------------------------------------
management:
  endpoints:
    web:
      exposure:
        include: "*"

image-20200722144351017

在需要刷新代码的类中加入刷新配置的注解

@RestController
@RefreshScope(proxyMode = ScopedProxyMode.DEFAULT)  //不重启服务实现数据的刷新
public class ConfigController {
    Logger logger = LoggerFactory.getLogger(getClass());
    @Value("${name}")
    private  String name;

    @GetMapping("/demo")
    public String demo01(){
        logger.info("name{}",name);
        return "configClient ok:"+name;
    }
}

修改之后在访问

  • 发现并没有自动刷新配置?

  • 必须调用刷新配置接口才能刷新配置

手动调用刷新配置接口

POST http://localhost:8999/actuator/refresh  #向当前微服务发送post请求 刷新数据

curl -X POST http://localhost:8889/actuator/refresh

image-20211230164320886

image-20211230164345207

Spring Cloud Alibaba 微服务工具集

阿里巴巴版本: 2.2.1

Boot版本: 2.2.5

1.简介

Spring Cloud Alibaba provides a one-stop solution for distributed application development. It contains all the components required to develop distributed applications, making it easy for you to develop your applications using Spring Cloud.

  • spring cloud 用来解决微服务系统中(分布式系统)解决方案

  • spring cloud alibaba 用来解决微服务系统中解决方案

With Spring Cloud Alibaba, you only need to add some annotations and a small amount of configurations to connect Spring Cloud applications to the distributed solutions of Alibaba, and build a distributed application system with Alibaba middleware.

2.环境搭建

<parent>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-parent</artifactId>
     <version>2.2.5.RELEASE</version>
</parent>
​
<properties>
    <spring.cloud.alibaba.version>2.2.1.RELEASE</spring.cloud.alibaba.version>
    <spring.cloud-version>Hoxton.SR6</spring.cloud-version>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
</properties>
​
<dependencyManagement>
​
    <dependencies>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-dependencies</artifactId>
            <version>${spring.cloud.alibaba.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>${spring.cloud-version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

3.Nacos

什么是Nacos Name Service(服务注册与发现) & Configurations Services(统一配置中心)

image-20200727202422243

  • home

  • Nacos 致力于帮助您发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据及流量管理。

准备环境
  • 1.64 bit OS,支持 Linux/Unix/Mac/Windows,推荐选用 Linux/Unix/Mac。必须满足

  • 2.64 bit JDK 1.8+;下载 & 配置。 必须满足

  • 3.Maven 3.2.x+;下载 & 配置。

1.下载nacos

image-20200727202936158

2.解压缩安装包到指定位置
  • [root@localhost ~]# tar -zxvf nacos-server-1.3.1.tar.gz

  • bin 启动nacos服务的脚本目录

  • conf nacos的配置文件目录

  • target nacos的启动依赖存放目录

  • data nacos启动成功后保存数据的目录

image-20200727203852405

3.启动安装服务
  • linux/unix/mac启动 打开终端进入nacos的bin目录执行如下命令 ./startup.sh -m standalone

  • windows启动 在 cmd中 执行 startup.cmd -m standalone

4.访问nacos的web服务管理界面

image-20200727210727986

开发服务注册到nacos

<!--引入nacos client的依赖-->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

1.配置注册地址

server.port=8789  #指定当前服务端口                                                                         
                            
spring.application.name=nacosclient     # 指定服务名称                                                                    
spring.cloud.nacos.server-addr=localhost:8848    #指定nacos服务地址
spring.cloud.nacos.discovery.server-addr=${spring.cloud.nacos.server-addr} #指定注册中心地址                            
management.endpoints.web.exposure.include=*  #暴露所有web端点
​
-------------------------------------------
server:
  port: 8851
spring:
  application:
    name: ORDERS
  cloud:
    nacos:
      server-addr: localhost:8848

2.加入启动服务注册注解

image-20200727213320726

3.查看nacos的服务列表

image-20200727213221604

点击详情

image-20230222211539268

image-20230222211611157

点击编辑

image-20230222211748920

权重生效需要设置负载均衡策略为NacosRule,否则不生效

NACOSCLIENT:   # 被调用服务的名称
   ribbon:
     NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule

使用nacos作为配置中心

1.创建项目并引入nacons配置中心依赖

<!--引入nacos client 依赖-->
<dependency>
  <groupId>com.alibaba.cloud</groupId>
  <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

<!--引入配置中心依赖-->
<dependency>
   <groupId>com.alibaba.cloud</groupId>
   <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>

2.配置配置中心地址

spring.cloud.nacos.server-addr=localhost:8848								# 远程配置中心的地址
spring.cloud.nacos.config.server-addr=${spring.cloud.nacos.server-addr}     # 去指定nacos地址读取配置
spring.cloud.nacos.config.group=DEFAULT_GROUP								# 读取配置的分组
spring.cloud.nacos.config.file-extension=properties					        # 指定读取文件后缀
spring.application.config.name=config										# 指定读取文件的前缀	


----------------------------------------------
spring:
  cloud:
    nacos:
      server-addr: localhost:8848
      config:
        group: DEFAULT_GROUP
        name: user-dev
        file-extension: yml
 		namespace: public

3.在nacos中创建配置

image-20200728211633327

image-20200728211924796

4.编写控制器测试配置读取情况

@RestController
@Slf4j
public class HelloController {
    //注入配置
    @Value("${user.name}")
    private String username;
    @GetMapping("/hello/config")
    public String config(){
        log.info("用户名: [{}]",username);
        return username;
    }
}

5.启动项目测试配置读取

2.DataId
1.DataId
- 用来读取远程配置中心的中具体配置文件其完整格式如下:
- ${prefix}-${spring.profile.active}.${file-extension}
	a. prefix 默认为 spring.application.name 的值,也可以通过配置项 spring.cloud.nacos.config.prefix来配置。
	b. spring.profile.active 即为当前环境对应的 profile,详情可以参考 Spring Boot文档。 注意:当 spring.profile.active 为空时,对应的连接符 - 也将不存在,dataId 的拼接格式变成 ${prefix}.${file-extension}
	c. file-exetension 为配置内容的数据格式,可以通过配置项 spring.cloud.nacos.config.file-extension 来配置。目前只支持 properties 和 yaml 类型。
实现自动配置刷新
 1.自动刷新
- 默认情况下nacos已经实现了自动配置刷新功能,如果需要刷新配置直接在控制器中加入@RefreshScope注解即可
@RestController
@Slf4j
@RefreshScope
public class HelloController {
    //注入配置
    @Value("${user.name}")
    private String username;
    @GetMapping("/hello/config")
    public String config(){
        log.info("用户名: [{}]",username);
        return username;
    }
}

日志频繁刷新,可设置日志输出的级别进行调整

# Nacos 注册中心客户端心跳日志禁用 get changedGroupKeys:[] 
logging:
  level:
    com.alibaba.nacos.client.config.impl: WARN

sentinel 流量卫兵

什么是sentinel

image-20200730205725897

sentinel使用

- sentinel提供了两个服务组件:
	一个是 sentinel 用来实现微服务系统中服务熔断、降级等功能。                         这点和hystrix 类似
	一个是 sentinel dashboard 用来监控微服务系统中流量调用等情况 流控  熔断  降级 配置。 这点和hystrix  dashboard类似
1. sentinel dashboard的安装
# 1.下载
- https://github.com/alibaba/Sentinel/releases
2.启动
  • 仪表盘是个jar包可以直接通过java命令启动 如: java -jar 方式运行 默认端口为 8080

  • java -Dserver.port=9191 -jar sentinel-dashboard-1.7.2.jar

3.访问web界面
4.登录
  • 用户名&密码: sentinel

image-20200730212001214

2.sentinel 实时监控服务
# 1.创建项目引入依赖
<!--引入nacos client依赖-->
<dependency>
  <groupId>com.alibaba.cloud</groupId>
  <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

<!--引入sentinel依赖-->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
2.配置
server.port=8789
spring.application.name=nacosclient
spring.cloud.nacos.server-addr=localhost:8848
spring.cloud.nacos.discovery.server-addr=${spring.cloud.nacos.server-addr}

spring.cloud.sentinel.enabled=true											 # 开启sentinel 默认开启
spring.cloud.sentinel.transport.dashboard=localhost:9191 # 连接dashboard
spring.cloud.sentinel.transport.port=8719

-------------------------------
sentinel:
      enabled: true
      transport:
        dashboard: localhost:9090  # 连接dashboard
        port: 8719
3.启动服务

image-20200730214911616

4.访问dashboard界面查看服务监控
  • 发现界面什么都没有?

  • 默认情况下sentiel为延迟加载,不会在启动之后立即创建服务监控,需要对服务进行调用时才会初始化

image-20200730215003082

5.开发服务
@RestController
@Slf4j
public class SentinelController {
    @GetMapping("/sentinel/test")
    public String test(){
        log.info("sentinel test");
        return "sentinel test ";
    }

    @GetMapping("/sentinel/test1")
    public String test1(){
        log.info("sentinel test1");
        return "sentinel test1 ";
    }
}
6.启动进行调用

image-20200730215227292

7.查看监控界面

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值