【原创】SpringCloud:基于Spring Cloud netflix全家桶搭建一个完整的微服务架构系统


整体架构

服务规划

注册服务 实例 主机 端口 说明 访问地址
EUREKASERVER EurekaServer1 ek1.com 9001 eureka服务1 http://ek1.com:9001
EUREKASERVER EurekaServer2 ek2.com 9002 eureka服务2 http://ek2.com:9002
SCSERVER sc-server1 scServer1 8001 远端服务1 动作:http://scserver1:8001/user/getName
手工下线:http://scserver1:8001/health/adjust?status=down
SCSERVER sc-server2 scServer2 8002 远端服务2 动作:http://scserver2:8001/user/getName
SCCLIENT1 sc-client1 scclient1 7001 客户端服务1;
支持RestTemplate,Feign通过Ribbon负载均衡调用远端服务;
支持Hystrix服务容错治理、监控等
http://scclient1:7001/test/getUserNameByFeign
http://scclient1:7001/test/getUserNameByRestTemplate
http://scclient1:7001/hystrix
http://scclient1:7001/actuator/hystrix.stream
SCCLIENT2 sc-client2 scclient2 7002 客户端服务2 支持从config配置中心获取配置;
测试操作:http://scclient2:7002/test/getConfig
SCGATEWAY sc-gateway scgateway 8888 zuul网关服务;支持限流等 http://scgateway:8888/scclient1/test/getUserNameByFeign
http://scgateway:8888/scserver/user/getName
开启前缀访问:http://scgateway:8888/api/v1/scserver/user/getName
路由监控:http://scgateway:8888/actuator/routes
SCCONFIG sc-config scconfig 9999 配置中心 配置从本地读取:http://scconfig:9999/scClient2/local
配置从git读取:http://scconfig:9999/netflix/scClient2-local.properties
SCADMIN sc-admin scadmin 8080 Spring Boot Admin;
支持邮件、钉钉告警;
TODO 支持集成logback实时显示日志等
http://scadmin:8080/wallboard
- - sczipkin 9411 zipkin链路跟踪 http://sczipkin:9411/zipkin

完整Host配置

192.168.0.12 ek1.com
192.168.0.12 ek2.com
192.168.0.12 scServer1
192.168.0.12 scServer2
192.168.0.12 scclient1
192.168.0.12 scclient2
192.168.0.12 scgateway
192.168.0.12 sczipkin
192.168.0.12 scadmin
192.168.0.12 scconfig

配置Eureka Server注册中心(集群模式)

Host配置

192.168.0.12 ek1.com
192.168.0.12 ek2.com

maven依赖


    org.springframework.cloud
    spring-cloud-starter-netflix-eureka-server


    org.springframework.cloud
    spring-cloud-starter-netflix-eureka-client

ek1 application.properties

#服务器端口
server.port=9001
#应用名称,高可用的两个eureka节点必须保持一致
spring.application.name=eurekaServer

#eureka多节点配置
#是否注册
eureka.client.enabled=true
#是否将自己注册到其他Eureka Server,默认为true需要
eureka.client.register-with-eureka=true
#是否从eureka server获取注册信息, 需要
eureka.client.fetch-registry=true
#设置服务注册中心的URL,用于client和server端交流
#此节点应向其他节点发起请求
eureka.client.serviceUrl.defaultZone=http://ek2.com:9002/eureka/
#主机名,必填
eureka.instance.hostname=ek1.com
#分组名称
#eureka.instance.app-group-name=eurekaServerGroup
#是否开启自我保护
eureka.server.enable-self-preservation=true
#触发自我保护阀值
eureka.server.renewal-percent-threshold=0.85
#失效服务间隔
eureka.server.eviction-interval-timer-in-ms=6000

ek2 application.properties

#服务器端口
server.port=9002
#应用名称,两个eureka节点必须保持一致
spring.application.name=eurekaServer

#eureka多节点配置
#是否将自己注册到其他Eureka Server,默认为true需要
eureka.client.register-with-eureka=true
#是否从eureka server获取注册信息, 需要
eureka.client.fetch-registry=true
#设置服务注册中心的URL,用于client和server端交流
#此节点应向其他节点发起请求
eureka.client.serviceUrl.defaultZone=http://ek1.com:9001/eureka/
#主机名,必填
eureka.instance.hostname=ek2.com
#分组名称
#eureka.instance.app-group-name=eurekaServerGroup
management.endpoint.shutdown.enabled=true

应用开启EurekaServer

@EnableEurekaServer // 启用Eureka服务端

EurekaServer配置优化

TODO

EurekaServer地址

  • http://ek1.com:9001/
  • http://ek2.com:9002/

配置Eureka Clients

Host配置

192.168.0.12 scServer1
192.168.0.12 scServer2

maven依赖


    org.springframework.cloud
    spring-cloud-starter-netflix-eureka-client

scServer1 application.properties

server.port=8001
spring.application.name=scServer

#eureka client config
#是否注册
eureka.client.enabled=true
#是否将自己注册到其他Eureka Server,默认为true需要
eureka.client.register-with-eureka=true
#是否从eureka server获取注册信息, 需要
eureka.client.fetch-registry=true
#设置服务注册中心的URL,用于client和server端交流
#重要说明:client默认向配置的第1个server地址注册,第1个注册不成功后再依次向第2个,第3个注册(最多重试3次)
eureka.client.serviceUrl.defaultZone=http://ek1.com:9002/eureka/,http://ek2.com:9002/eureka/
#主机名,必填
eureka.instance.hostname=scServer1
#续约发送间隔默认30秒,心跳间隔
eureka.instance.lease-renewal-interval-in-seconds=5
#表示client间隔多久去拉取服务注册信息,默认为30秒,如果要迅速获取服务注册状态,可以缩小该值,比如5秒
eureka.client.registry-fetch-interval-seconds=5
#续约到期时间(默认90秒)
eureka.instance.lease-expiration-duration-in-seconds=90
#将实例IP注册到Eureka Server上(多网卡适用,其他服务可通过IP访问)
#eureka.instance.prefer-ip-address=true
#eureka.instance.ip-address=192.168.0.12
#是否开启健康检测,对应EurekaServer控制台的Status状态
eureka.client.healthcheck.enabled=true

scServer2 application.properties

server.port=8002
spring.application.name=scServer

#eureka client config
#是否注册
eureka.client.enabled=true
#是否将自己注册到其他Eureka Server,默认为true需要
eureka.client.register-with-eureka=true
#是否从eureka server获取注册信息, 需要
eureka.client.fetch-registry=true
#设置服务注册中心的URL,用于client和server端交流
#重要说明:client默认向配置的第1个server地址注册,第1个注册不成功后再依次向第2个,第3个注册(最多重试3次)
eureka.client.serviceUrl.defaultZone=http://ek1.com:9002/eureka/,http://ek2.com:9002/eureka/
#主机名,必填
eureka.instance.hostname=scServer2
#续约发送间隔默认30秒,心跳间隔
eureka.instance.lease-renewal-interval-in-seconds=5
#表示client间隔多久去拉取服务注册信息,默认为30秒,如果要迅速获取服务注册状态,可以缩小该值,比如5秒
eureka.client.registry-fetch-interval-seconds=5
#续约到期时间(默认90秒)
eureka.instance.lease-expiration-duration-in-seconds=90
#将实例IP注册到Eureka Server上(多网卡适用,其他服务可通过IP访问)
#eureka.instance.prefer-ip-address=true
#eureka.instance.ip-address=192.168.0.12
#是否开启健康检测,对应EurekaServer控制台的Status状态
eureka.client.healthcheck.enabled=true

测试地址

  • http://scserver1:8001/user/getName
  • http://scserver2:8002/user/getName
  • 手工下线:http://scserver1:8001/health/adjust?status=down

配置客户端服务调用(基于RestTemplate)及负载均衡(Ribbon)

说明:

  • 请参考sc-client1应用代码实现;
  • spring-cloud-starter-netflix-eureka-client依赖中已存在Ribbon依赖信息(不需要重复导包)。

RestTemplate客户端配置

/**
 * Web配置
 *
 * @author binglang
 * @date 2021/11/24 10:44
 **/
@Configuration
public class WebConfig implements WebMvcConfigurer {
    // 开启负载均衡
    @LoadBalanced
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

客户端调用

    /**
     * 测试RestTemplate服务调用
     */
    @GetMapping(value = "/getUserNameByRestTemplate")
    // 整合Hystrix配置服务降级
    // @HystrixCommand(fallbackMethod = "fallback")
    public String getUserNameByRestTemplate() {
        String serviceUrl = "http://SCSERVER/user/getName";
        String username = restTemplate.getForObject(serviceUrl, String.class);

        return username;
    }

测试地址

  • http://scclient1:7001/test/getUserNameByRestTemplate

配置客户端服务调用(基于Feign)及负载均衡(Ribbon)

说明:请参考sc-client1应用代码实现。

maven依赖


    org.springframework.cloud
    spring-cloud-starter-openfeign

应用开启Feign客户端

@EnableFeignClients

实现流程

// 二方库sc-common定义服务公共接口
com.binglangaimo.sccommon.service.feign.ICommonUserService

// 服务提供方sc-server1,sc-server2必须实现此接口
com.binglangaimo.scserver1.controller.UserController

// 服务调用方sc-client1定义带@FeignClient注解接口
com.binglangaimo.scclient1.service.TestFeignService

// 服务调用
com.binglangaimo.scclient1.controller.TestController#getUserNameByFeign()

测试地址

  • http://scclient1:7001/test/getUserNameByFeign

配置服务容错Hystrix

maven依赖


    org.springframework.cloud
    spring-cloud-starter-netflix-hystrix

应用开启Hystrix断路器

@EnableCircuitBreaker // 开启Hystrix断路器

应用配置

说明:参考sc-client1/src/main/resources/application.properties

#feign配置
#feign调用开启支持hystrix断路器
feign.hystrix.enabled=true

三种实现方式:

参考代码实现:com.binglangaimo.scclient1.service.TestFeignService

  • 请求方法上加@HystrixCommand注解
  • @FeignClient(value = "SCSERVER", fallback = TestFeignServiceFallBack.class)
  • @FeignClient(qualifier = "testFeignServiceClient", value = "SCSERVER", fallbackFactory = TestFeignServiceFallBackFactory.class)

配置Hystrix Dashboard

maven依赖


    org.springframework.cloud
    spring-cloud-starter-netflix-hystrix-dashboard

应用开启Hystrix Dashboard

@EnableHystrixDashboard // 开启Hystrix Dashboard

应用配置

#hystrix配置,不配置会报错,参考:https://www.cnblogs.com/itsharehome/p/15628220.html
hystrix.dashboard.proxy-stream-allow-list=scclient1

#actuator监控参数
#开启所有端点(不推荐),生产环境仅开启需要的即可
management.endpoints.web.exposure.include=*

监控地址

  • home: http://scclient1:7001/hystrix
  • stream: http://scclient1:7001/actuator/hystrix.stream

配置服务跟踪Sleuth+Zipkin

说明:需要被跟踪的服务都需要做以下配置。可参考sc-client1实现。

原理说明

  • sleuth负责收集跟踪信息并通过http请求发送给zipkin server;
  • zipkin server将跟踪信息进行存储(默认内存,可以配置使用mysql,ES等),以及提供RESTful API;
  • zipkin ui通过调用api进行数据展示。

maven依赖


    org.springframework.cloud
    spring-cloud-starter-sleuth


    org.springframework.cloud
    spring-cloud-starter-zipkin

应用配置

#zipkin配置
#zipkin server地址
spring.zipkin.base-url=http://sczipkin:9411/
#采样频率
spring.sleuth.sampler.rate=10

下载并启动Zipkin

// 下载命令
curl -sSL https://zipkin.io/quickstart.sh | bash -s

// 启动zipkin
java -jar zipkin.jar

测试地址

  • http://sczipkin:9411/zipkin
  • 效果如下:

配置服务网关Zuul

说明:请参考sc-gateway应用实现。

maven依赖


    org.springframework.cloud
    spring-cloud-starter-netflix-zuul

应用配置

sc-gateway/src/main/resources/application.properties

应用开启zuul网关

@EnableZuulProxy // 开启Zuul网关

测试地址

  • http://scgateway:8888/scclient1/test/getUserNameByFeign
  • http://scgateway:8888/scserver/user/getName
  • 开启前缀访问:http://scgateway:8888/api/v1/scserver/user/getName
  • 开启监控:http://scgateway:8888/actuator/routes

配置服务配置中心Spring Cloud Config

说明:sc-config为配置中心(Config Server);sc-client2支持从配置中心获取配置(Config client)。

config服务端

maven依赖


    org.springframework.cloud
    spring-cloud-config-server

应用配置

重要说明:

  • Config Server支持配置从本地或远端(git or svn)获取配置信息;
  • 项目config目录用于存储配置信息(支持eureke client、actuator等公共配置通过include方式引入);
  • Config Server配置远端获取配置支持SSH密钥验证方式,但并不支持读取本地密钥文件获取密钥信息,只能将密钥字符串配置在应用配置文件中。我对MultipleJGitEnvironmentProperties bean进行了增强实现,使其支持此功能。
server.port=9999
spring.application.name=scConfig

#config注册中心配置
#使用local配置
#spring.profiles.active=native
#spring.cloud.config.server.native.search-locations=file:xxx/WWW/study/springcloud/config
#使用git配置
spring.cloud.config.server.git.uri=git@gitee.com:binglangaimo/springcloud.git
spring.cloud.config.server.git.strict-host-key-checking=false
spring.cloud.config.server.git.private-key=file:C:/Users/xxx/.ssh/id_rsa #支持从本地文件中读取密钥信息,保证了密钥信息的安全
spring.cloud.config.server.git.ignore-local-ssh-settings=false
spring.cloud.config.server.git.default-label=netflix
spring.cloud.config.server.git.search-paths=config

应用开启Config Server

@EnableConfigServer

测试验证

  • local:http://scconfig:9999/scClient2/local
  • git:http://scconfig:9999/netflix/scClient2-local.properties

config 客户端

maven依赖


    org.springframework.cloud
    spring-cloud-config-client

应用配置(bootstrap.properties)

spring.application.name=scClient2
spring.profiles.active=local

#从注册中心获取配置
spring.cloud.config.uri=http://scconfig:9999
spring.cloud.config.fail-fast=true

测试获取配置

  • http://scclient2:7002/test/getConfig

配置服务总控Spring Boot Admin

说明:

  • 参考sc-admin应用实现;
  • Spring Boot Admin需要依赖于actuator收集信息,所以请将所有需要监控的服务配置actuator。

maven依赖


    de.codecentric
    spring-boot-admin-starter-server


    de.codecentric
    spring-boot-admin-server-ui

应用配置

server.port=8080
spring.application.name=scAdmin

#此处为eureka client公共配置,不重复粘贴了

#此处为actuator公共配置,不重复粘贴了

应用开启AdminServer

@EnableAdminServer // 开启Admin监控

发送钉钉消息

com.binglangaimo.scadmin.notify.DingDingNotifier实现类

测试地址

  • http://scadmin:8080/applications
  • 监控效果:

代码仓库

我的个人gitee-https://gitee.com/binglangaimo/springcloud。(重点申明:代码仅供学习参考使用,未经作者授权,请勿用于商业用途)。