SpringCloud史上最全 入门到精通

文章目录

SpringCloud相关介绍及应用

一、架构设计演变

1、单体项目

单体项目将所有的服务部署到一起,如果某个模块出现问题,直接影响整个服务。

2、分布式项目

整个项目的各个模块分开部署,如果某个模块出现问题,只影响局部服务,不会导致整个服务宕机。
(1)优点:实现了架构的松耦合;
(2)缺点:为了实现分布式运用,需采用其他的组件进行维护,维护的成本很高;
分布式项目架构如图所示:

3、微服务形式

   将单个应用程序作为一套小型的服务进行开发,每个服务都运行在自己的进程中,各个服务之间通过通讯机制进行通讯(一般是Http的API)。各个服务一般按照业务进行拆分,进行全自动部署。简而言之,就是在分布式的前提下,让项目**独立**运行,一切部署都是**全自动**的实现。<br />**(1)微服务的优点**<br />1)每个服务足够内聚,足够小,代码容易理解,聚焦于一个指定的业务;<br />2)开发简单,开发效率高;<br />3)微服务能够被小团队(2-5人)单独开发;<br />4)微服务是松耦合的,是具有功能意义的服务,无论在开发阶段还是部署阶段都是独立的;<br />5)微服务可以使用不同的语言进行开发;<br />6)易于和第三方集成,微服务允许容易且灵活的方式继承自动部署,通过持续集成工具实现,集成工具有Jenkins、Hudson、bamboo等;<br />7)微服务容易理解、修改和维护;<br />8)微服务允许融合最新技术;<br />9)微服务只注重业务逻辑,不会和HTML、CSS等前段语言相混合;<br />10)每个微服务都可以有自己的存储能力,可以独立连接数据库,也可以有统一的数据库;<br />**(2)微服务的缺点**<br />1)开发人员要处理分布式系统的复杂性;<br />2)多服务运维难度,随着服务的增加,运维压力增大;<br />3)系统部署依赖;<br />4)服务间的通讯成本高;<br />5)数据一致性;<br />6)系统集成测试;<br />7)性能监控;

二、微服务思想SOA

SOA,即是面向服务的架构:
将不同功能的服务进行拆分,不同的服务之间通过良好的接口和契约联系。接口采用中立的方式定义,独立于实现服务的硬件平台、操作系统以及编程语言,是的构建在各个项目中的服务,以统一和通用的方式进行交互。

三、微服务框架-SpringCloud

SpringCloud是微服务落地的一种技术,它为开发人员提供了快速构建分布式系统需要的模式工具(如配置管理、断路器、只能路由、微代理等)。为最常见的分布式系统模式提供了一种简单易用的编辑模型,可帮助开发人员构建弹性、可靠、协调的应用程序。
Springcloud结构图如下:

四、SpringCloud项目构建

注意:SpringCloud项目构建是基于SpringBoot基础之上的。

1、构建步骤

(1)构建父项目jt-springcloud

作用:集中管理jar包;

1)创建maven工程

打包方式:pom;

2)导入jar包

jar包导入完成后打包;
SpringCloud需要依赖的jar包如下:

       <!--导入springBoot依赖包 -->
       <parent>
              <groupId>org.springframework.boot</groupId>
              <artifactId>spring-boot-starter-parent</artifactId>
              <version>2.1.1.RELEASE</version>
              <relativePath />
       </parent>
       <properties>
              <java.version>1.8</java.version>
       </properties>
 
       <!--依赖管理,用于管理spring-cloud的依赖 -->
       <dependencyManagement>
              <dependencies>
                     <dependency>
                            <groupId>org.springframework.cloud</groupId>
                            <artifactId>spring-cloud-dependencies</artifactId>
                            <version>Finchley.SR2</version>
                            <type>pom</type>
                            <scope>import</scope>
                     </dependency>
              </dependencies>
       </dependencyManagement>
       <repositories>
              <repository>
                     <id>spring-milestones</id>
                     <name>Spring Milestones</name>
                     <url>https://repo.spring.io/milestone</url>
                     <snapshots>
                            <enabled>false</enabled>
                     </snapshots>
              </repository>
       </repositories>
      
       <!--需要依赖的其他jar包 -->
 
       <dependencies>
              <!--导入springCloudjar包 -->
              <dependency>
                     <groupId>org.springframework.cloud</groupId>
                     <artifactId>spring-cloud-stream</artifactId>
              </dependency>
 
              <!--引入springBoot jar包 -->
              <dependency>
                     <groupId>org.springframework.boot</groupId>
                     <artifactId>spring-boot-starter-web</artifactId>
              </dependency>
 
              <dependency>
                     <groupId>org.springframework.boot</groupId>
                     <artifactId>spring-boot-starter-test</artifactId>
                     <scope>test</scope>
              </dependency>
             
              <!--<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency> -->
 
              <!--支持热部署 -->
              <dependency>
                     <groupId>org.springframework</groupId>
                     <artifactId>springloaded</artifactId>
                     <version>1.2.8.RELEASE</version>
              </dependency>
 
              <dependency>
                     <groupId>org.springframework.boot</groupId>
                     <artifactId>spring-boot-devtools</artifactId>
              </dependency>
 
              <!--整合redis -->
              <dependency>
                     <groupId>redis.clients</groupId>
                     <artifactId>jedis</artifactId>
              </dependency>
              <dependency>
                     <groupId>org.springframework.data</groupId>
                     <artifactId>spring-data-redis</artifactId>
              </dependency>
 
              <!--导入pojo插件 -->
              <dependency>
                     <groupId>org.projectlombok</groupId>
                     <artifactId>lombok</artifactId>
              </dependency>
             
              <!--使用druid整合mysql数据库 -->
              <dependency>
                     <groupId>mysql</groupId>
                     <artifactId>mysql-connector-java</artifactId>
                     <scope>runtime</scope>
              </dependency>
 
              <!--阿里数据源 -->
              <dependency>
                     <groupId>com.alibaba</groupId>
                     <artifactId>druid</artifactId>
                     <version>1.1.12</version>
              </dependency>
 
              <!--mybatis-plus配置 -->
              <dependency>
                     <groupId>com.baomidou</groupId>
                     <artifactId>mybatis-plus-boot-starter</artifactId>
                     <version>3.0.6</version>
              </dependency>
       </dependencies>

(2)构建服务接口jt-springcloud-interfance
作用:接口中保存了项目通讯的接口信息.和pojo等公共信息,其作用类似于common项目的作用;

1)创建maven工程

选择创建项目类型为:Maven
Module;

父项目:jt–parent;
打包方式:jar;


2)创建工具类 、公用pojo等

测试时,创建User的Pojo;
实际项目中根据项目中的需求新建java类;
创建完毕后,将项目打包;

(3)构建服务提供者jt-springcloud-provider-8000

作用:完成相应的业务逻辑;

1)创建maven工程

项目类型:Maven Module;
父项目:jt-springcloud-provider-8000
注意:在Springcloud中各个服务分别占用不同的端口,为方便明了,可将端口附在服务名之后,此处的端口为8000,实际项目中根据实际情况而定;

2)添加接口项目的依赖

需要使用接口中的工具类或公用类,就要将jt-springcloud-interface作为依赖添加到项目中;

3)完成业务逻辑

测试时:完成user表的增删改查;
实际项目中:根据实际情况完成业务逻辑;

4)配置application.yml配置文件

需要定义服务访问的端口号、根目录以及数据源,配置如下:

#服务端口及路径的配置
server:
  port: 8000   #单点登录的端口
  servlet:
    context-path: /    #该配置可以不配,默认配置为“/”
spring:
  #数据源的配置
  datasource:
    #引入druid数据源
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/jtdb?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true
    username: root
    password: 123456
#mybatis-plush配置
mybatis-plus:
  type-aliases-package: com.jt.pojo
  mapper-locations: classpath:/mybatis/mappers/*.xml
  configuration:
    map-underscore-to-camel-case: true  #自动开启驼峰规则映射

注意:在配置yml文件时要注意缩进层级关系和空格问题。

(4)构建服务消费者jt-springcloud-consumer-8020

1)创建maven工程

项目类型:Maven Module;
父项目:jt-parent;
注意:此处测试的端口为8020;

2)添加接口项目的依赖

添加jt-springcloud-interface的依赖,使用其工具类和其他公用的pojo;

3)配置application.yml配置文件

需要定义服务访问的端口号、根目录,如下图所示:

server:
  port: 8020
  servlet:
    context-path: /

注意:消费者端不需要连接数据库,则不需要配置数据源,需要在主启动类上添加如下配置,排除数据源的加载,否则程序启动会报错:
**

@SpringBootApplication(exclude=DataSourceAutoConfiguration.class)

4)编写controller,远程获取数据

a.RestTemplate对象的创建

springcloud中的封装远程调用是使用Http协议,本次案例中实现远程调用的对象是RestTemplate,通过这个对象执行远程调用;
RestTemplate对象的创建通过配置类实现:

@Configuration
public class RestTemplateConfig {
       @Bean
       public RestTemplate getTemplate() {
              return new RestTemplate();
       }
}

b.远程调用获取数据
编写controller,使用restTemplate对象调用其方法向提供者端发起请求获取数据,测试程序能够调通,表示配置成功;
注意:到此,服务提供者和消费者之间的调用能够正常跑通,表示项目基础搭建完成,要实现Springcloud微服务的管理,则要借助于Springcloud的几个重要组件完成,后面依次介绍。

五、SpirngCloud各大组件介绍

1、注册中心Eureka

(1)作用

负责服务的调度。

(2)实现原理

注册中心内部有心跳检测机制,可以实时坚挺服务状态,同时记录服务IP、端口、服务名称等信息,方便消费者的调用。原理图如下:

(3)工作流程

1)启动注册中心;
2)服务的提供者讲自己的信息写入注册中心,注册中心将各个服务维护成一份服务列表;
3)启动消费者后,消费者首先连接注册中心,获取服务列表数据,并保存到本地,方便之后的调用;
4)有多个提供者时,客户端(消费者)内部有负载均衡策略(默认轮巡),挑选一个服务发起HttpClient调用,获取数据;
5)当服务提供者宕机后,注册中心的心跳检测(1分钟)发现提供者宕机,则动态维护服务列表数据,标记宕机(添加down属性);
6)当服务列表发生变化。消费者会再次同步数据,最终实现数据一致性。这时如果有消费者请求时,将陷入阻塞状态,满足AP原则;
注意:与Zookeeper不同的是,服务宕机时,Zookeeper要求立即同步数据,满足CP原则。

(4)注册中心的搭建

A、搭建注册中心

1)创建Maven工程jt-springcloud-Eureka-7000

项目类型:Maven Module;
父项目:jt-springcloud;
打包方式:jar;
注意:此处测试端口号为:7000。

2)添加jar包

添加注册中心Eureka相关jar包,如下所示:

<dependencies>
       <!--添加eureka注册中心 -->
       <dependency>
              <groupId>org.springframework.cloud</groupId>
                     <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
       </dependency>
</dependencies>

3)配置application.yml配置文件
此处测试端口号为7000,详细配置如下:

server:
  port: 7000                      #定义注册中心端口
eureka:
  server:
    enable-self-preservation: true  #设定自我保护模式 默认值为true 不建议关闭
  instance:
    hostname: localhost        #eureka服务的实例名称
  client:
    register-with-eureka: false   #表示注册中心 不会注册自己本身
    fetch-registry: false         #表示自己就是注册中心,不需要检索服务
    service-url: 
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

4)编辑主启动类
主启动类上添加注解,开启注册中心的开关:

@EnableEurekaServer   //开启注册中心服务

5)启动注册中心,检测是否搭建成功
启动注册中心,访问http://localhost:7000/,成功显示注册中心Eureka管理界面表示搭建成功。

B、配置服务的提供者端

注意:在Springcloud中,其实没有消费者和提供者之说,消费者和提供者都是客户端,因为,消费者和提供者添加的都是客户端的jar包。

1)添加jar包

在提供者的pom.xml中添加如下依赖,以支持注册中心:

<!--添加eureka 客户端地址 -->
<dependency>
       <groupId>org.springframework.cloud</groupId>
       <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

2)编辑application.yml配置文件
在已有的配置基础之上添加如下配置:
注意:
a.application属于spring的属性,应与dataSource同级;
b.application的name属性:表示多个提供者(多台服务部署)的统一名称,多台提供者的名称要一致;
c.instance-id:表示每个服务独有名称,一般以共同名称加端口组成;
示例如下:

spring:
       application:   #定义服务名称
           name: provider-user
   
eureka:
  client:
    service-url:
      defaultZone: http://localhost:7000/eureka
  instance:
    instance-id: provider-user-8000                #定义微服务的名称
    prefer-ip-address: true                        #是否显示IP和端口  

3)在主启动类中开启注册中心客户端服务

@EnableEurekaClient    //开启客户端服务

4)启动项目检测
启动提供者项目,刷新Eureka管理界面,出现开启的服务名称即表示配置成功,如下图所示:

C、配置服务的消费者端

1)添加jar包

在消费者的pom.xml中添加如下依赖,以支持注册中心:

<!--添加eureka 客户端地址 -->
<dependency>
       <groupId>org.springframework.cloud</groupId>
       <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

(2)编辑application.yml配置文件

在已有的配置基础之上添加如下配置:
注意:
a. register-with-eureka: 表示是否将自己的信息注册到Eureka中,消费者不需要注册自己的信息,所以填false**;
b. defaultZone**:表示连接注册中心的集群(可能有多个注册中心);

示例如下:

eureka:
  client:
    register-with-eureka: false  #不会将自己的信息注册到eureka中
    service-url:
      defaultZone: http://localhost:7000/eureka  #链接注册中心集群 

3)在主启动类中开启注册中心客户端服务
@EnableEurekaClient    //开启客户端服务

4)启动项目,进行测试

启动消费者端,调用程序,看是否能调通,能调用表示配置成功。
consumer中远程访问路径:http://provider-user(统一的服务名)/path;

2、客户端负载均衡Ribbon

(1)定义

Ribbon是SpringCloud中客户端负载均衡的组件,负载均衡在客户端实现。
注意:nginx是服务端的负载均衡。

(2)服务端和客户端负载均衡对比

1)服务端负载均衡

a.如果服务端负载均衡宕机,则直接影响整个服务项目;
b.服务端负载均衡是一种集中式的相应,性能低;

2)客户端负载均衡

a.客户端负载均衡在用户发起请求之前已经分配到服务器地址,请求速度快;
b.如果客户端宕机,只影响单个客户;

(3)配置方式

1)在获取RestTemplate连接对象的配置类的创建对象的方法上添加注解:@LoadBalanced ;
表示在客户端添加负载均衡。
2)在这个类中定义方法,定义负载均衡的策略:
a. RoundRobinRule:轮巡策略;
b.RandomRule:随机策略;
c. AvailabilityFilteringRule: 首先过滤掉故障机或者并发链接数超过阈值的服务器,剩余的机器轮询配置;
d. WeightedResponseTimeRule:服务器影响时间越快,则权重越高;
c. BestAvailableRule:最大可用策略,即先过滤出故障服务器后,选择一个当前并发请求数最小的;
代码示例如下:

@Configuration
public class RestTemplateConfig {
       @Bean
       @LoadBalanced  //开启负载均衡
       public RestTemplate getTemplate() {
              return new RestTemplate();
       }
       /**
       *配置均衡策略
       */
       @Bean
       public IRule getIrule() {
              return new RoundRobinRule();
       }
}

3、声明式http客户端:Feign

(1)定义

Feign是一个声明式、模板化的Http客户端,可以简化客户端的编码,使用户直接通过接口的方式声明式的调用,内部集成了Ribbon,实现负载均。
注意:Feign是简化服务的调用,是配置在服务的消费者端或者接口模块中。

(2)作用

简化客户端代码,通过接口,直接调用服务。

(3)配置方式

1)导入jar包

本例配置在接口模块中。
在接口项目:jt-springcloud-interface中导入如下jar包,引入Feign的支持:

<dependencies>
       <!--引入Feign支持 -->
       <dependency>
              <groupId>org.springframework.cloud</groupId>
              <artifactId>spring-cloud-starter-openfeign</artifactId>
       </dependency>
</dependencies>

2)定义接口

在jt-springcloud-interface项目中定义调用服务提供者的接口,接口有如下要求:
a.在接口类上添加注解:@FeignClient(value=“服务提供者的服务名称”),指定需要调用的服务的名称;
b.在接口中定义所要调用的服务中的方法,需与提供者中保持一致。
代码示例如下:

@FeignClient(value="provider-user")  //指定服务名称
public interface UserService {
       //获取用户json信息
       @RequestMapping("/findAll")
       public List<User>findAll();
 
       @RequestMapping("saveUser")
       public String saveUser(@RequestBody User user);
 
       //获取提供者一的数据
       @RequestMapping("/getMsg")
       public String getMsg();
}

3)编辑消费者

在消费者中注入定义好的接口,通过接口远程调用。
代码示例如下:

@RestController
@RequestMapping("/consumer")
public class UserController {
      
       @Autowired
       private UserService userService;
      
       //实现查询方法(这里只举一个例子,其他需自行补充)
       @RequestMapping("/findAll")
       public List<User> findAll(){
             
              return userService.findAll();
       }    
}

注意:使用feign时,如果controller接收参数时使用了@PathVariable注解,则要写明该注解的value属性,即是:@PathVariable(value=“参数名”),否则会报IllegalStateException异常。

4)消费者主启动类中开启Feign客户端

在主启动类上添加如下注解,开启Feign客户端:

@EnableFeignClients

5)测试

依次启动注册中心、服务提供者、消费者,进行测试。

4、断路器Hystrix

(1)服务扇出

1)什么是服务扇出?
多个微服务之间相互调用的时候,A调用B和C,C又要依靠调用D或其他服务,称之为服务扇出。
2)会导致的问题
多个服务相互调用,如果其中被依赖的一个服务(比如服务D)执行较慢,或者不可用,导致服务的调用者(服务C)占用大量系统资源,最终导致服务崩溃。

(2)定义及作用

问题:在分布式系统里许多依赖可能会调用失败,为了避免长时间的等待或者抛出异常,需要使用熔断机制解决。
定义及作用:Hystrix是断路器,是一个用于处理分布式系统的延时和容错的开源库。**Hystrix能够保证当服务单元发生故障后,通过短路机制,返回一个满足预期处理条件的数据,**避免服务长时间没有响应或者报错等影响,提升软件的可靠性。
通过熔断机制,可实现服务的降级。
注意:断路器机制是对后台的保护,需配置在服务的提供者端。

(3)断路器配置方式

A、普通方式

1)导入jar包

在服务的提供者端

<!--添加断路器配置 -->
<dependency>
       <groupId>org.springframework.cloud</groupId>
       <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>

2)编写服务提供者端的controller中的熔断方法

a.在业务类中定义每个方法熔断后需要执行的方法;
b.在相应的业务方法上添加注解:@HystrixCommand(fallbackMethod=“方法名”),指定熔断后执行的方法名;

       @RequestMapping("/findAll")
       @HystrixCommand(fallbackMethod="hystrix_findAll")
       public List<User>findAll(){
             
              returnuserService.findAll();
       }
       public List<User>hystrix_findAll(){
              List<User>userList = newArrayList<User>();
              User user = newUser();
                     user.setId(0)
                            .setName("")
                            .setAge(0)
                            .setSex("");
              userList.add(user);
              returnuserList;
       }

3)在主启动类中开启熔断机制

在服务的提供者端的主启动类中添加注解:

@EnableHystrix//开启熔断机制。

4)测试

在业务方法中制造异常,分别开启和关闭异常,测试熔断机制。

B、接口形式

说明:一般将断路器配置到服务端,可以返回有效地数据。但是如果服务端程序宕机了,这时断路器机制不能生效。因此,可以将断路器配置到接口中。具体配置方式如下:

1)导入jar包

在接口项目jt-springcloud-interface中添加支持熔断器的依赖,如下:

<!--添加断路器配置 -->
<dependency>
       <groupId>org.springframework.cloud</groupId>
       <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>

2)编辑调用接口熔断器工厂FallBackFactory

通过这个工厂,创建熔断后的接口对象,该对象重写了服务提供者的所有业务方法,当熔断后,执行重写的方法,代码如下:
注意:这个工厂对象的创建要交给Spring管理,需添加@Component注解。

@Component
public class UserServiceFallbackFactory implements FallbackFactory<UserService>{
       @Override
       public UserService create(Throwable cause) {
              //当程序调用发生异常时采用接口熔断,此处采用匿名内部类,重写熔断后执行的方法。
              return new UserService() {
                     @Override
                     public String saveUser(User user) {
                            return"后台服务器异常,调用熔断机制";
                     }
                     @Override
                     public String getMsg() {
                            return"后台服务器异常!!!!!";
                     }
                     @Override
                     public List<User>findAll() {
                            return new ArrayList<User>();
                     }
              };
       }
}

(3)编辑Feign的调用接口

在接口方法的调用对象上添加注解,指定熔断工厂,熔断后才能执行该工厂中的方法,代码如下:

//编辑服务名称,定义熔断器工厂
@FeignClient(value="provider-user",fallbackFactory=UserServiceFallbackFactory.class )     
public interface UserService {
       //获取用户json信息
       @RequestMapping("/findAll")
       public List<User>findAll();
}

(4)编辑消费者端的application.yml配置文件

启动熔断机制,指定超时时间,配置如下:

feign:
  hystrix:
    enabled: true                 #启动熔断器机制 !!!!!!!!!!!!!
 
hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 3000  #设定断路器超时时间
#说明:当服务端宕机机.由客户端中的配置返回数据,节省时间开销.

5)启动测试
制造异常,测试熔断。

5、仪表盘监控DashBoard

(1)作用

Hystrix
DahBoard实时监控Hystrix的运行情况。
注意:
1)DashBoard只能对一台服务进行监控。而实际情况中通常不止一个服务,为了方便监控,需将多个DashBoard的数据汇总在一个DashBoard中展现,需要用到工具Turbine。Turbine工具后面进行讲解。
2)DashBoard是监控熔断机制的,所以在使用监控时,要开启熔断器。
3)如果采用的是接口熔断机制,在服务端需要被监控的方法上添加@HystrixCommond注解即可。

(2)项目搭建方式

A、监控端的搭建

1)创建项目jt-springcloud-dashboard-server

项目类型:Maven Module;
打包方式:jar;

2)导入jar包
<dependencies>
       <!--添加断路器配置 -->
       <dependency>
              <groupId>org.springframework.cloud</groupId>
              <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
       </dependency>
 
       <!--配置hystrix监控 -->
       <dependency>
              <groupId>org.springframework.cloud</groupId>
              <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
       </dependency>
</dependencies>

3)配置application.yml配置文件

此处测试的端口号为9000:

server:
       port: 9000

3)在主启动类中开启DashBoard监控

在主启动类上添加一下配置,开启Hystrix的监控:

@EnableHystrixDashboard    //启动仪表盘监控程序

4)启动测试

启动项目,访问:http://localhost:9000/hystrix,出现一下界面,表示搭建成功:

B、客户端实现服务的监控

1)导入jar包

在需要监控的服务的提供者端添加如下jar包,引入达式board的支持:

<!--添加监控  -->
<dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

2)编辑配置类

两种方式:
a.在主启动类添加注解:

@EnableCircuitBreaker//开启实时监控;
   这种方式默认的服务当前监控页面地址如下:<br />       http://localhost:8000/actuator/hystrix.stream<br /> <br />b.在服务的提供者端,定义配置类,实现监控的拦截,代码如下(可自定义监控名称和监控路径):
@Configuration
publicclassDashboardConfig {
 
   //定义监控的相关参数
   @Bean
   public ServletRegistrationBean<Servlet>   getServlet(){
       HystrixMetricsStreamServletstreamServlet =new HystrixMetricsStreamServlet();
			 ServletRegistrationBean<Servlet> registrationBean =
         						new ServletRegistrationBean<>(streamServlet);
			 registrationBean.setLoadOnStartup(1);
       //设定监控路径
       registrationBean.addUrlMappings("/actuator/hystrix.stream");
       //设定监控的名称
			 registrationBean.setName("HystrixMetricsStreamServlet");
			 return  registrationBean;
   }
}

3)查看监控页面效果

打开监控首页:http://localhost:9000/hystrix
在页面搜索框输入当前服务监控路径,到达监控页面,如下:
http://localhost:8000/actuator/hystrix.stream

注意:如果页面显示为loading…,表示服务还没有被消费,调用一下服务就可以了。

4)监控页面数据表示

监控状态信息表示如下:

关键词 表达含义
Success 请求成功次数
Bad Request 错误请求次数
Timeout 超时请求次数
Rejected 拒绝请求次数
Failure 请求失败次数
Error 失效异常数

6、服务端路由器Zuul

(1)定义级作用

     Zuul是Netflix开源的微服务网关,Springcloud对zuul进行了整合和增强,在Springcloud中,zuul担任网关的角色,对发送到服务端的请求进行一些预处理(比如安全验证、动态路由、负载均衡等),可拦截无效的请求,实现了请求的转发和响应。<br />      **zuul的核心是一系列的filters,**其作用可以类比Servlet框架的Filter或者spring的拦截器。

(2)项目搭建方式

A、zuul网管端创建jt-zuul

1)项目创建

项目类型:Maven Project;
打包方式:jar;
注意:网关是单独的项目,不属于微服务的模块,不能创建jt-springcloud-parent的子项目。

2)导入jar包,配置pom.xml配置文件
<!--导入springBoot依赖包 -->
    <parent>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-parent</artifactId>
       <version>2.0.5.RELEASE</version>
       <relativePath/>
    </parent>
    <properties>
       <java.version>1.8</java.version>
    </properties>
    <!--依赖管理,用于管理spring-cloud的依赖 -->
    <dependencyManagement>
       <dependencies>
           <dependency>
              <groupId>org.springframework.cloud</groupId>
              <artifactId>spring-cloud-dependencies</artifactId>
              <version>Finchley.SR2</version>
              <type>pom</type>
              <scope>import</scope>
           </dependency>
       </dependencies>
    </dependencyManagement>
    <repositories>
       <repository>
           <id>spring-milestones</id>
           <name>Spring Milestones</name>
           <url>https://repo.spring.io/milestone</url>
           <snapshots>
              <enabled>false</enabled>
           </snapshots>
       </repository>
    </repositories>
 
    <dependencies>
       <!--导入springCloudjar包 -->
       <dependency>
           <groupId>org.springframework.cloud</groupId>
           <artifactId>spring-cloud-stream</artifactId>
       </dependency>
       <!--引入springBoot jar包 -->
       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-web</artifactId>
       </dependency>
 
       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-test</artifactId>
           <scope>test</scope>
       </dependency>
       <!--支持热部署 -->
       <dependency>
           <groupId>org.springframework</groupId>
           <artifactId>springloaded</artifactId>
           <version>1.2.8.RELEASE</version>
       </dependency>
       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-devtools</artifactId>
       </dependency>
       <!--引入springBoot监控 -->
       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-actuator</artifactId>
       </dependency>
       <!--添加eureka客户端地址 -->
       <dependency>
           <groupId>org.springframework.cloud</groupId>
           <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
       </dependency>
       <dependency>
           <groupId>org.springframework.cloud</groupId>
           <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
       </dependency>
    </dependencies>

3)配置application.yml配置文件
server:
  port: 9050
  servlet:
    context-path: /
spring:
  application:   #定义服务名称
    name: springcloud-zuul
eureka:
  client:
    service-url:
      defaultZone: http://localhost:7000/eureka
  instance:
    instance-id: springcloud-zuul-9050             #定义微服务的名称
    prefer-ip-address: true                        #是否显示IP和端口
   
zuul:
  #prefix: /                             #通过统一的公共前缀访问
  #ignored-services: springcloud-user    #禁止通过某个服务名访问
  ignored-services: "*"                 #禁止通过全部服务名访问
  routes:
    user-service:
      serviceId: consumer-user           #需要服务端映射路径名称,需要映射的是服务端就写服务端服务名称,要映射的是消费者端,就写消费者端服务名称。
      path: /userService/**         #映射对应的url,访问需在浏览器中输入,代替服务名,再在后面追加访问路径。

4)编辑主启动类

在主启动类上添加@EnableZuulProxy注解,启动zuul:

@EnableZuulProxy  //启动zuul配置

B、消费者端配置

1)编辑application.yml配置文件

开启消费者的服务,将消费者注入注册中心,配置如下:

spring:
  application:#定义服务名称,如果是多个相同的服务,则名称必须相同
    name: consumer-user
 
eureka:
  client:
    service-url:
      defaultZone: http://localhost:7000/eureka
  instance:
    instance-id: consumer-user-8020                #定义微服务的名称

2)访问测试

发起请求,进行测试。
**访问路径:**localhost:9050/zuul中配置的path值(映射后的路径)/每个方法的访问路径,例如:本例中的访问路径是:localhost:9050/userService/consumer/select

7、配置中心

(1)定义及作用

配置中心是使用GitHub(使用方法见后面)统一管理配置文件。项目开发时,配置文件可以统一的进行管理,以后使用配置文件时,只需要联网从网络中动态获取配置文件信息即可。

(2)配置中心的搭建

A、配置中心端

1)创建项目jt-springcloud-config-9080

项目类型:Maven Module;
父项目:jt-parent;
打包类型:jar;

2)导入jar包
<dependencies>
    <!--springcloud配置中心  -->
    <dependency>
       <groupId>org.springframework.cloud</groupId>
       <artifactId>spring-cloud-config-server</artifactId>
    </dependency>
      
    <!--eclipse中整合github中防止冲突  -->
    <dependency>
        <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit</artifactId>
    </dependency>

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

<!--        actuator完善页面监控依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>


</dependencies>

3)配置application.yml配置文件

此处测试端口号为9080,在这里定义配置中心的服务名称,以及连接远程github账户。

server:
  port: 9080
spring:
  application:
    name: springcloud-config   #定义服务的名称
  cloud:
    config:
      server:
        git:
          uri: https://github.com/junping1991/student_1811.git
         #连接远程github账户
4)编辑主启动类

在主启动类中添加@EnableConfigServer注解,开启配置中心设置:

@EnableConfigServer      //开启配置中心设置
@SpringBootApplication
publicclassSpringCloud_Config {
   
    publicstaticvoidmain(String[] args) {
       SpringApplication.run(SpringCloud_Config.class, args);
    }
}
5)上传配置文件

测试:将provider中的yml配置文件上传到远程仓库中。


B、配置中心的客户端配置
1)导入jar包

在客户端添加jar包,引入配置中心的支持:


       <!--eclipse中整合github中防止冲突  -->
		<dependency>
		    <groupId>org.eclipse.jgit</groupId>
		    <artifactId>org.eclipse.jgit</artifactId>
		</dependency>
	<!--客户端配置-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>

   

(2)配置bootstrap.yml配置文件
#bootstrap的优先级高于application.yml
#系统级别的配置(高于用户级别的配置)
#只能识别application.yml和boostrap.yml,别的名字不能识别
spring:
  cloud:
    config:
      #springcloud-config采用的是sv(服务器客户端)的架构模式
      uri: http://localhost:9080#服务器地址
      name: config-client         #需要从gitee上读取的资源名称
      profile: dev                #开发模式  test是测试模式
      label: master               #geitee的分支
package com.common.springcloud.controller;
/**
 * 写这个controller这是为了证明客户端能通过服务端从gitee拿到数据
 * 这里把数据打印出来了
 * 可以不写这个controller,在bootstrap.yml和application.yml写配置就行了
 */

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ConfigClientController {
    @Value("${spring.application.name}")
    private String applicationName;

    @Value("${eureka.client.service-url.defaultZone}")
    private String eurekaServer;

    @Value("${server.port}")
    private String port;

    @RequestMapping("/config")
    public String getConfig() {
        return "applicationName:"+applicationName+
                "eurekaServer:"+eurekaServer+
                "port:"+port;
    }
}

实战测试

在任何一个模块,加入 客户端的依赖

	<!--        导入giteeg关于dept配置要用的依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>
编辑bootstrap.yml配置文件
#bootstrap的优先级高于application.yml
spring:     
  cloud:
    config:
      name: eureka           #加载远程配置中心文件名称
      profile: dev  #动态加载开发环境配置文件
      label:  master              #获取master默认分支
      uri: http://localhost:9080/

先启动 配置中心的服务端 ,就是 9080 ,然后测试 一个 数据
localhost:9080/eureka-dev.yml
最后就可以了

六、GitHub的使用

1、在GitHub官网注册账号并登陆

2、使用

(1)新建仓库


(2)远程连接GitHub,将远程仓库下载到本地


(3)使用工具上传/下载文件GitHub Desktop

1)在本次仓库中创建新的文件


2)推送文件到远程服务器


3)检查远程仓库是否有文件

八 、消息总线 SpringCloudBus

SpringCloud Bus集成了市面上常用的消息中间件(rabbit mq,kafka等),连接微服务系统中的所有的节点,当有数据变更的时候,可以通过消息代理广播通知微服务及时变更数据,例如微服务的配置更新。

SpringCloud Bus 解决了什么问题 ?

Bus组件的作用,当我们把配置文件保存在Git当中,由Git进行管理,一旦配置字段的值进行改变
不需要采用服务器重启的方式去更新配置。

解决了微服务数据变更,及时同步的问题。

刷新客户端服务
在这里插入图片描述

刷新服务端服务

在这里插入图片描述

配置服务端

(1) 修改cloud_config工程的pom.xml,引用依赖

pom.xml
 <!-- 消息 总线 依赖 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-bus</artifactId>
        </dependency>

        <!-- 整合 Rabbitmq 的依赖 -->

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-stream-binder-rabbit</artifactId>
        </dependency>

(2)修改application.yml ,添加配置

applicaion.yml

  rabbitmq:
    host: 127.0.0.1

management:
  endpoints:
    web:
      exposure:
        include: bus-refresh #开放出去的端口

配置客户端

(1 ) 我们还是以(Provider)生产者模块为例,加入消息总线

<!-- 消息 总线 依赖 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-bus</artifactId>
        </dependency>

        <!-- 整合 Rabbitmq 的依赖 -->

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-stream-binder-rabbit</artifactId>
        </dependency>

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

在客户端也加上


  rabbitmq:
    host: 127.0.0.1

management:
  endpoints:
    web:
      exposure:
        include: bus-refresh #开放出去的端口

(2)在码云的配置文件中配置Mysql的连接地址:
数据库 改成 001

 url: jdbc:mysql://localhost:3306/clouddb001?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true        # 数据库名称              # 数据库名称

我们在 新建一个数据库 ,clouddb001 在数据库当中 加入 部门 修改部
在这里插入图片描述

(3)启动cloud_config 、cloud_provider和cloud_eureka 看是否正常运行

(4) 我们改完之后 码云地址之后,再次发出请求,看看

结果 肯定还是之前一样 ,
postman测试
Url: http://127.0.0.1:9100/actuator/bus-refresh
Method: post

自定义配置的读取

(1)修改码云上的配置文件,增加自定义配置

bilibili:
		ip: 127.0.0.1

(2)在cloud_provider工程中新建controller

@RestController 
public class TestController {

 @Value("${sms.ip}") 
 private String ip; 
 
 @RequestMapping(value = "/ip", method = RequestMethod.GET) 
 public String ip() {
  return ip; 
  } 
}

(3)运行测试看是否能够读取配置信息 ,OK.

(4)修改码云上的配置文件中的自定义配置

clicli:
		ip: 127.0.0.1

(5)通过postman测试
Url: http://127.0.0.1:9100/actuator/bus-refresh
Method: post

测试后观察,发现并没有更新信息

这是因为我们的 controller少了一个注解@RefreshScope 此注解用于刷新配置

@RefreshScope
@RestController 
public class TestController {

 @Value("${sms.ip}") 
 private String ip; 
 
 @RequestMapping(value = "/ip", method = RequestMethod.GET) 
 public String ip() {
  return ip; 
  } 
}

发布了55 篇原创文章 · 获赞 125 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/qq_42897427/article/details/104258438