「环境搭建」SpringCloud环境搭建以及常用组件

什么是Spring Cloud

SpringCloud 是在Spring生态环境下,用于构建可靠微服务应用的一系列组件的统称,提供的功能包括但不限于服务治理,接口式Http调用,负载均衡,服务降级以及熔断,数据健康,网关,配置中心,消息总线等。

SpringCloud中常用组件及作用

  • Eureka:云端服务发现,一个基于 REST 的服务,用于定位服务,以实现云端中间层服务发现和故障转移。
  • OpenFeign:Feign是一种声明式、模板化的HTTP客户端
  • Ribbon:提供云端负载均衡,有多种负载均衡策略可供选择,可配合服务发现和断路器使用
  • Hystrix:熔断器,容错管理工具,旨在通过熔断机制控制服务和第三方库的节点,从而对延迟和故障提供更强大的容错能力
  • Spring Cloud Config:配置管理工具包,让你可以把配置放到远程服务器,集中化管理集群配置,目前支持本地存储、Git以及Subversion
  • Zuul:Zuul 是在云平台上提供动态路由,监控,弹性,安全等边缘服务的框架。Zuul 相当于是设备和 Netflix 流应用的 Web 网站后端所有请求的前门
  • Spring Cloud Bus:事件、消息总线,用于在集群(例如,配置变化事件)中传播状态变化,可与Spring Cloud Config联合实现热部署。
  • Consul:封装了Consul操作,consul是一个服务发现与配置工具,与Docker容器可以无缝集成

Maven环境初步搭建

主项目的依赖引入

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
 
    <!--引入Springboot-->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.2.RELEASE</version>
    </parent>
    <groupId>org.example</groupId>
    <artifactId>springcloudtest</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <!--对子项目进行管理-->
    <modules>
        <module>provider-8100</module>
        <module>provider-8101</module>
        <module>provider-8102</module>
        <module>consumer-8200</module>
        <module>consumer-8201</module>
        <module>eureka-server-8300</module>
        <module>eureka-server-8301</module>
        <module>springcloud-hystrix-dashboard-8400</module>
    </modules>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <spring-cloud.version>Hoxton.RELEASE</spring-cloud.version>
        <log4j.version>1.2.17</log4j.version>
    </properties>
 
    <dependencyManagement>
        <!--对springcloud的版本进行统一管理-->
        <dependencies>
            <!--spring cloud Hoxton.SR1-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Hoxton.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
 
            <!--spring cloud 阿里巴巴-->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>2.1.0.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
 
            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>${log4j.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
 
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <fork>true</fork>
                    <addResources>true</addResources>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

Eruaka的使用

Maven引入

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

配置文件

server:
  port: 8300
spring:
  application:
    name: springcloud-eureka-server-8300
eureka:
  instance:
    ## 此处需要修改DNS 将该域名映射到本机上。不直接用localhost,一个实例只能被一个域名使用
    hostname: server1.com
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/,http://server2.com:8301/eureka/
 

启动两个Eureka服务器实例

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

「环境搭建」SpringCloud环境搭建以及常用组件

创建Provider

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>springcloudtest</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
 
    <artifactId>provider-8100</artifactId>
 
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
 
    </dependencies>
 
</project>
spring:
  application:
    name: provider
server:
  port: 8100
 
eureka:
  instance:
    instance-id: ${spring.application.name}:${server.port}
  client:
    fetch-registry: true
    register-with-eureka: true
    service-url:
      defaultZone: http://server1.com:8300/eureka/,http://server2.com:8301/eureka/
  #Eureka地址
@SpringBootApplication
@EnableDiscoveryClient
public class Provider {
    public static void main(String[] args) {
        SpringApplication.run(Provider.class, args);
    }
}

因此我们就完成了,eureka服务端的集群与客户端的注册

「环境搭建」SpringCloud环境搭建以及常用组件

Openfeign的使用

OpenFeign是一个在集成了Ribbon的声明式,模版化客户端,我们先注册三个provider到EruekaServer中

「环境搭建」SpringCloud环境搭建以及常用组件

接下来我们再启动一个接入OpenFeign的客户端:消费者

加入maven依赖

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

给RestTemplate加上负载均衡注解

@Configuration
public class RestConfig {
 
    @Bean
    @LoadBalanced
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }
 
}

使用@FeignClient定义http客户端

@Component
@FeignClient(name = "provider", fallback = ProductFallbackServieImpl.class)
public interface ProductService {
 
    @GetMapping("/product/provider/serviceInfo")
    String getServiceInfo();
 
    @GetMapping("/product/provider" + "/getById?id={id}")
    String selectById(@PathVariable("id") Long id);
}

定义失败回掉类用于服务降级

@Component
public class ProductFallbackServieImpl implements ProductService{
    @Override
    public String getServiceInfo() {
        return "服务器开小差了";
    }
 
    @Override
    public String selectById(Long id) {
        return "服务器开小差了";
    }
}

最后在启动类上加上@EnableFeignClients注解,然后启动

访问provider接口返回对应的端口信息

「环境搭建」SpringCloud环境搭建以及常用组件

如图可以知道,消费者端请求到了不同端口的服务提供者。

Hystrix的使用

引入maven依赖

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

服务降级

在微服务中,为避免下游服务异常,导致上游服务异常或资源占用,通常采取特殊处理,来保证服务的正常进行,比如我们在订单服务调用库存服务发生异常时,通常不直接返回异常给用户,而是采用降级函数,替代原函数返回内容,例如上一块内容使用的异常处理函数。

「环境搭建」SpringCloud环境搭建以及常用组件

在配置文件上加上:

feign:
  hystrix:
    enabled: true # fegin默认关闭hystrix服务

并在启动类上加上 @EnableCircuitBreaker注解。

我们访问provider一个异常接口,可以看到最终返回了降级函数的内容。

「环境搭建」SpringCloud环境搭建以及常用组件

服务熔断

服务熔断发生在服务提供者,当某个接口产生了一定的异常后,将该接口的调用关闭,断路器打开,使用降级函数,一段时间后重新尝试半打开状态,就是尝试放进一些流量,如果正常,则将断路器关闭,避免不必要的资源占用。

@HystrixCommand(
            // 降级函数
            fallbackMethod = "selectByIdFallbackHandler", commandProperties = {
            // 是否启用服务熔断
            @HystrixProperty(name = "circuitBreaker.enabled", value = "true"),
            // 请求阈值
            @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"),
            // 时间窗口
            @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000"),
            // 错误比率
            @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "50")
    })

表示请求次数大于10次,且错误比率占50%以上时,打开断路器,10秒后尝试半开状态。

服务端发生的降级函数为 我失败了啊啊啊 

「环境搭建」SpringCloud环境搭建以及常用组件

当发生熔断之后,直接调用降级函数

「环境搭建」SpringCloud环境搭建以及常用组件

Hystrix- dashboard的使用

应用暴露运行信息

Hystrix-dashboard是Hystrix-dashboard的健康仪表盘,要想被监控,我们首先需要引入一个监控信息依赖

<!-- actuator监控信息完善 -->
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

然后添加信息暴露配置

适用于springboot 2.x以上

management:
  endpoints:
    web:
      exposure:
        include: "*"

在应用启动时,我们需要看到一行,表示成功。

2021-09-12 23:45:25.181  INFO 38634 --- [           main] o.s.b.a.e.web.EndpointLinksResolver      : Exposing 17 endpoint(s) beneath base path '/actuator'

新建Hystrix Dashboard项目

添加maven依赖

<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-devtools</artifactId>
</dependency>

启动springboot应用程序

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

访问HystrixDashboard

「环境搭建」SpringCloud环境搭建以及常用组件

如果点击进去一直在loading,需要访问一次添加@HystrixCommand注解的接口,才会开始显示,

「环境搭建」SpringCloud环境搭建以及常用组件

如图当失败过多时,断路器开启

「环境搭建」SpringCloud环境搭建以及常用组件

当断路器打开时,即使接口参数正确,也直接返回降级函数的内容

「环境搭建」SpringCloud环境搭建以及常用组件

 

上一篇:Eureka服务端源码解析


下一篇:「环境搭建」SpringCloud环境搭建以及常用组件