Table of Contents generated with DocToc

microservicecloud

Microservice based on Springcloud,follwer me to build a com.styz.com.styz.microservice instance step by step

插件推荐

在搭建项目之前先推荐两款很好用的IDEA插件,至于插件做什么用的,自己百度吧!

1.MyBatisCodeHelper-Pro

2.lombok

建立父工程Microservicecloud

点击 File——>new——>Project 新建maven工程项目

修改pom.xml文件

  1. <dependencyManagement>
  2. <dependencies>
  3. <dependency>
  4. <groupId>org.springframework.cloud</groupId>
  5. <artifactId>spring-cloud-dependencies</artifactId>
  6. <version>${spring-cloud.version}</version>
  7. <type>pom</type>
  8. <scope>import</scope>
  9. </dependency>
  10. <dependency>
  11. <groupId>mysql</groupId>
  12. <artifactId>mysql-connector-java</artifactId>
  13. <version>5.1.30</version>
  14. </dependency>
  15. <dependency>
  16. <groupId>org.springframework.boot</groupId>
  17. <artifactId>spring-boot-devtools</artifactId>
  18. <version>2.0.3.RELEASE</version>
  19. </dependency>
  20. <dependency>
  21. <groupId>org.springframework.boot</groupId>
  22. <artifactId>spring-boot-starter-test</artifactId>
  23. <scope>test</scope>
  24. </dependency>
  25. <dependency>
  26. <groupId>org.springframework.security</groupId>
  27. <artifactId>spring-security-test</artifactId>
  28. <scope>test</scope>
  29. </dependency>
  30. <dependency>
  31. <groupId>org.projectlombok</groupId>
  32. <artifactId>lombok</artifactId>
  33. <version>${lombok.version}</version>
  34. </dependency>
  35. <dependency>
  36. <groupId>com.alibaba</groupId>
  37. <artifactId>druid</artifactId>
  38. <version>1.1.0</version>
  39. </dependency>
  40. </dependencies>
  41. </dependencyManagement>
  42. <repositories>
  43. <repository>
  44. <id>spring-milestones</id>
  45. <name>Spring Milestones</name>
  46. <url>https://repo.spring.io/milestone</url>
  47. <snapshots>
  48. <enabled>false</enabled>
  49. </snapshots>
  50. </repository>
  51. <repository>
  52. <id>repository.springframework.maven.release</id>
  53. <name>Spring Framework Maven Release Repository</name>
  54. <url>http://maven.springframework.org/milestone/</url>
  55. </repository>
  56. <repository>
  57. <id>org.springframework</id>
  58. <url> http://maven.springframework.org/snapshot</url>
  59. </repository>
  60. <repository>
  61. <id>spring-milestone</id>
  62. <name>Spring Maven MILESTONE Repository</name>
  63. <url>http://repo.spring.io/libs-milestone</url>
  64. </repository>
  65. <repository>
  66. <id>spring-release</id>
  67. <name>Spring Maven RELEASE Repository</name>
  68. <url>http://repo.spring.io/libs-release</url>
  69. </repository>
  70. </repositories>

搭建Employ员工服务

创建数据库

1.执行microserivcecloud-database中的Employ.sql文件创建员工服务需要用到的表

当然也可以自己考出来执行

  1. use db;
  2. SET STORAGE_ENGINE = InnoDB;
  3. DROP TABLE IF EXISTS `employ`;
  4. CREATE TABLE `employ` (
  5. `id` bigint(20) NOT NULL COMMENT '员工编号',
  6. `name` varchar(48) NOT NULL COMMENT '名字',
  7. `departmentId` bigint(10) NOT NULL COMMENT '部门编号',
  8. `datasourceId` varchar(64) NOT NULL COMMENT '数据存储位置',
  9. PRIMARY KEY (`id`)
  10. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  11. insert into employ(id,name,departmentId,datasourceId) values(1,"zhansan",1,DATABASE());
  12. insert into employ(id,name,departmentId,datasourceId) values(2,"lisi",2,DATABASE());
  13. insert into employ(id,name,departmentId,datasourceId) values(3,"wangwu",3,DATABASE());
  14. insert into employ(id,name,departmentId,datasourceId) values(4,"maliu",4,DATABASE());

2.创建springboot+mybatis整合项目

2.1创建microservicecloud-api 子模块项目用于存放公共的接口和实体

修改pom.xml文件

  1. <!--添加lombok依赖-->
  2. <dependency>
  3. <groupId>org.projectlombok</groupId>
  4. <artifactId>lombok</artifactId>
  5. </dependency>

2.2利用MyBatisCodeHelper-Pro生成mybatis的mapper接口和数据库实体到microservicecloud-api中

生成结果如下

  1. com.styz.microservicecloud.entity.Employ #实体
  2. com.styz.microservicecloud.mapper.EmployMapper #mapper接口
  3. microservicecloud-api/src/main/resources/mapperxml/EmployMapper.xml #mapper.xml sql 文件

然后执行mvn install操作

2.3创建microservicecloud-employservice 模块

修改pom文件

  1. <dependencies>
  2. <dependency>
  3. <groupId>com.com.styz.microservicecloud</groupId>
  4. <artifactId>microservicecloud-api</artifactId>
  5. <version>${project.version}</version>
  6. </dependency>
  7. <dependency>
  8. <groupId>org.springframework.boot</groupId>
  9. <artifactId>spring-boot-starter-web</artifactId>
  10. </dependency>
  11. <dependency>
  12. <groupId>org.springframework.boot</groupId>
  13. <artifactId>spring-boot-starter</artifactId>
  14. </dependency>
  15. <dependency>
  16. <groupId>org.springframework.boot</groupId>
  17. <artifactId>spring-boot-devtools</artifactId>
  18. </dependency>
  19. <dependency>
  20. <groupId>com.alibaba</groupId>
  21. <artifactId>druid</artifactId>
  22. </dependency>
  23. <dependency>
  24. <groupId>org.mybatis</groupId>
  25. <artifactId>mybatis</artifactId>
  26. <version>3.5.1</version>
  27. </dependency>
  28. <dependency>
  29. <groupId>org.mybatis.spring.boot</groupId>
  30. <artifactId>mybatis-spring-boot-starter</artifactId>
  31. <version>1.3.0</version>
  32. </dependency>
  33. <dependency>
  34. <groupId>mysql</groupId>
  35. <artifactId>mysql-connector-java</artifactId>
  36. </dependency>
  37. </dependencies>

创建com.styz.microservicecloud包新建EmployServiceApplication启动类

  1. @SpringBootApplication
  2. @MapperScan("com.com.styz.microservicecloud.mapper")
  3. public class EmployServiceApplication {
  4. public static void main(String[] args) {
  5. SpringApplication.run(EmployServiceApplication.class);
  6. }
  7. }

然后创建com.styz.com.styz.microserivcecloud.service.EmployService接口以及其实现类

  1. public interface EmployService {
  2. /**
  3. * 获取所有员工
  4. * @return
  5. */
  6. public List<Employ> getAllEmployes();
  7. /**
  8. * 根据Id获取指定员工
  9. * @param id
  10. * @return
  11. */
  12. public Employ getEmployById(long id);
  13. }
  1. @Service
  2. public class EmployServiceImpl implements EmployService {
  3. @Autowired
  4. private EmployMapper employMapper;
  5. public List<Employ> getAllEmployes() {
  6. return employMapper.listAll();
  7. }
  8. public Employ getEmployById(long id) {
  9. return employMapper.selectByPrimaryKey(id);
  10. }
  11. }

然后创建com.styz.com.styz.microserivcecloud.controller.EmployController

  1. @RestController
  2. @RequestMapping("/employ")
  3. public class EmployController {
  4. @Autowired
  5. private EmployService employService;
  6. @RequestMapping("/getAllEmployes")
  7. public List<Employ> getAllEmployes(){
  8. return employService.getAllEmployes();
  9. }
  10. @RequestMapping("/getEmployById/{id}")
  11. public Employ getEmployById(@PathVariable("id")long id){
  12. return employService.getEmployById(id);
  13. }
  14. }

添加配置文件

  1. #应用程序使用的端口
  2. server:
  3. port: 8999
  4. #mybatis相关配置
  5. mybatis:
  6. config-location: classpath:mybatis/mybatis.cfg.xml
  7. type-alias-package: com.com.styz.microservicecloud.entity
  8. mapper-locations:
  9. - classpath*:mapperxml/*Mapper.xml
  10. #数据源配置
  11. spring:
  12. datasource:
  13. type: com.alibaba.druid.pool.DruidDataSource
  14. driver-class-name: com.mysql.jdbc.Driver
  15. url: jdbc:mysql://k8s-n1:3307/db
  16. username: root
  17. password: 123456
  18. dbcp2:
  19. min-idle: 5
  20. initial-size: 5
  21. max-idle: 10
  22. max-total: 20
  23. max-wait-millis: 10
  24. # 服务名称
  25. application:
  26. name: EmployService

mybatis/mybatis.cfg.xml

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE configuration
  3. PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  4. "http://mybatis.org/dtd/mybatis-3-config.dtd">
  5. <configuration>
  6. <settings>
  7. <!--二级缓存开启-->
  8. <setting name="cacheEnabled" value="true"/>
  9. </settings>
  10. </configuration>

注意:@MapperScan("com.com.styz.microservicecloud.mapper")必须扫描到API模块里的mapper接口

2.5 自嗨一下

访问http://localhost:8999/employ/getAllEmployes 查看一下是否正常返回

自此单机服务已经整合完毕

创建消费者服务microservicecloud-employconsummer

1.新建模块microservicecloud-employconsummer修改pom文件

  1. <dependencies>
  2. <dependency>
  3. <groupId>com.com.styz.microservicecloud</groupId>
  4. <artifactId>microservicecloud-api</artifactId>
  5. <version>${project.version}</version>
  6. </dependency>
  7. <dependency>
  8. <groupId>org.springframework.boot</groupId>
  9. <artifactId>spring-boot-starter</artifactId>
  10. </dependency>
  11. <dependency>
  12. <groupId>org.springframework.boot</groupId>
  13. <artifactId>spring-boot-starter-web</artifactId>
  14. </dependency>
  15. <dependency>
  16. <groupId>org.springframework.boot</groupId>
  17. <artifactId>spring-boot-devtools</artifactId>
  18. </dependency>
  19. </dependencies>

2.添加配置application.yml

  1. server:
  2. port: 8111
  3. spring:
  4. application:
  5. name: EmployComsummer
  6. devtools:
  7. restart:
  8. enabled: true

3.新建config配置类com.styz.com.styz.com.styz.microservice.config.ConsummerConfigBean

  1. @Configuration
  2. public class ConsummerConfigBean {
  3. /**
  4. * RestTemplate 封装了httpclient的实现能够简化我们对请求的访问
  5. * @return
  6. */
  7. @Bean
  8. public RestTemplate getRestTemplate(){
  9. return new RestTemplate();
  10. }
  11. }

4.创建消费者controller com.styz.com.styz.com.styz.microservice.controller.EmployConsumerController

  1. @RestController
  2. @RequestMapping("/comsummer")
  3. public class EmployConsumerController {
  4. //服务提供方的地址:http://localhost:8999/employ/getAllEmployes
  5. public static final String EMPLOY_PROVIDE_URL="http://localhost:8999/employ";
  6. @Autowired
  7. private RestTemplate restTemplate;
  8. @RequestMapping("/getById/{id}")
  9. public Employ getEmployById(@PathVariable("id") long id){
  10. return restTemplate.postForObject(EMPLOY_PROVIDE_URL+"/getEmployById/"+id,null,Employ.class);
  11. }
  12. @RequestMapping("/getAllEmployes")
  13. public List<Employ> getAllEmployes(){
  14. return restTemplate.postForObject(EMPLOY_PROVIDE_URL+"/getAllEmployes",null,List.class);
  15. }
  16. }

5.新建消费者启动类:com.styz.com.styz.com.styz.microservice.EmployComsumerApplication

  1. @SpringBootApplication
  2. public class EmployComsumerApplication {
  3. public static void main(String[] args) {
  4. SpringApplication.run(EmployComsumerApplication.class);
  5. }
  6. }

至此单体消费者实例已经完成。自嗨一下:访问http://localhost:8111/consummer/getById/1 看看能不能调用到服务端

提供的服务

Eureka注册中心搭建

Eureka主要的功能就是服务注册与发现。是Netflix公司下开源一款产品,功能比较单一

基于AP原则实现。cs架构模式实现,想要详细了Eureka可以百度。

单机模式

创建microservicecloud-registry-8211 模块

1.修改pom文件

  1. <dependencies>
  2. <dependency>
  3. <groupId>org.springframework.boot</groupId>
  4. <artifactId>spring-boot-starter</artifactId>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.springframework.boot</groupId>
  8. <artifactId>spring-boot-starter-web</artifactId>
  9. </dependency>
  10. <dependency>
  11. <groupId>org.springframework.boot</groupId>
  12. <artifactId>spring-boot-devtools</artifactId>
  13. </dependency>
  14. <dependency>
  15. <groupId>org.springframework.cloud</groupId>
  16. <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
  17. </dependency>
  18. <dependency>
  19. <groupId>org.springframework.boot</groupId>
  20. <artifactId>spring-boot-starter-actuator</artifactId>
  21. </dependency>
  22. </dependencies>
  23. <build>
  24. <plugins>
  25. <plugin>
  26. <groupId>org.springframework.boot</groupId>
  27. <artifactId>spring-boot-maven-plugin</artifactId>
  28. <configuration>
  29. <finalName>${project.name}</finalName>
  30. </configuration>
  31. </plugin>
  32. </plugins>
  33. </build>

2.创建com.styz.com.styz.com.styz.microservice.RegistryApplication_8211 启动类

  1. @SpringBootApplication
  2. @EnableEurekaServer
  3. public class RegistryApplication_8211 {
  4. public static void main(String[] args) {
  5. SpringApplication.run(RegistryApplication_8211.class,args);
  6. }
  7. }

3.配置文件


  1. spring:
  2. application:
  3. name: registry-8211
  4. eureka:
  5. instance:
  6. #euraka 服务器实例名称
  7. #主机名字需要修改host文件
  8. hostname: registry8211
  9. client:
  10. #false表示不向注册中心注册自己
  11. register-with-eureka: false
  12. #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
  13. fetch-registry: false
  14. service-url:
  15. #单机配置 http://${eureka.instance.hostname}:${server.port}/eureka
  16. #集群环境搭建:http://registry8212:8212/eureka/,http://registry8213:8213/eureka/
  17. defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka
  18. server:
  19. port: 8211

单机注册中心已经完成 访问 http://registry8211:8211/ 就会出现注册中心的界面

集群搭建

修改microservicecloud-registry-8211 模块

1.只需要修改bootstrap.yml中的

  1. defaultZone: http://registry8212:8212/eureka/,http://registry8213:8213/eureka/

拷贝microservicecloud-registry-8211 两份

microservicecloud-registry-8212 microservicecloud-registry-8213

同理修改


  1. spring:
  2. application:
  3. name: registry-8212
  4. eureka:
  5. instance:
  6. #euraka 服务器实例名称
  7. hostname: registry8212
  8. client:
  9. #false表示不向注册中心注册自己
  10. register-with-eureka: false
  11. #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
  12. fetch-registry: false
  13. service-url:
  14. #单机配置 http://${eureka.instance.hostname}:${server.port}/eureka
  15. #集群环境搭建
  16. defaultZone: http://registry8211:8211/eureka/,http://registry8213:8213/eureka/
  17. server:
  18. port: 8212

  1. spring:
  2. application:
  3. name: registry-8213
  4. eureka:
  5. instance:
  6. #euraka 服务器实例名称
  7. hostname: registry8213
  8. client:
  9. #false表示不向注册中心注册自己
  10. register-with-eureka: false
  11. #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
  12. fetch-registry: false
  13. service-url:
  14. #单机配置 http://${eureka.instance.hostname}:${server.port}/eureka
  15. #集群环境搭建
  16. defaultZone: http://registry8211:8211/eureka/,http://registry8212:8212/eureka/
  17. server:
  18. port: 8213

修改hosts文件

  1. 127.0.0.1 registry8213 registry8212 registry8211

至此集群模式搭建完毕,可以分别访问 http://registry8211:8211/ http://registry8212:8212/ http://registry8213:8213/

出现Eureka的界面表示成功。

注册服务到注册中心

新建microservicecloud-employproviderwithregistry

拷贝microserivicecloud-employservice中的代码和配置文件到microservicecloud-employproviderwithregistry 模块中

修改pom文件

  1. <!--添加注册中心依赖-->
  2. <dependency>
  3. <groupId>org.springframework.cloud</groupId>
  4. <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
  5. </dependency>
  6. <!--添加springboot监控依赖-->
  7. <dependency>
  8. <groupId>org.springframework.boot</groupId>
  9. <artifactId>spring-boot-starter-actuator</artifactId>
  10. </dependency>

添加bootstrap.yml文件

  1. #服务名称
  2. spring:
  3. application:
  4. name: EmployService
  5. eureka:
  6. client:
  7. service-url:
  8. #单机配置:http://localhost:8211/eureka
  9. defaultZone: http://registry8212:8212/eureka/,http://registry8213:8213/eureka/,http://registry8211:8211/eureka/
  10. # 修改注册服务的名字
  11. instance:
  12. instance-id: EmployService-8999
  13. # 防问路径可以显示IP地址
  14. prefer-ip-address: true
  15. # 添加服务Info信息
  16. info:
  17. app.name: EmployService-8999
  18. app.describution: 员工服务
  19. company.name: com.com.styz
  20. author.name: liuy
  21. build.artifactId: $project.artifactId$
  22. build.version: $project.version$

修改启动类com.styz.com.styz.microserivcecloud.EmployServiceApplication

添加@EnableEurekaClient注解

  1. @SpringBootApplication
  2. @MapperScan("com.com.styz.microservicecloud.mapper")
  3. @EnableEurekaClient
  4. public class EmployServiceApplication {
  5. public static void main(String[] args) {
  6. SpringApplication.run(EmployServiceApplication.class,args);
  7. }
  8. }

然后可以查看注册中心是否有服务注册进去了。

消费者调用

修改microservicecloud-employconsummer中的com.styz.com.styz.com.styz.microservice.controller.EmployConsumerController

中的

  1. // EMPLOYSERVICE为服务名称
  2. public static final String EMPLOY_PROVIDE_URL="http://EMPLOYSERVICE/employ";

修改pom添加eureka客户端依赖

  1. <dependency>
  2. <groupId>org.springframework.cloud</groupId>
  3. <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
  4. </dependency>

修改启动类添加服务发现注解@EnableDiscoveryClient

  1. @SpringBootApplication
  2. @EnableDiscoveryClient
  3. public class EmployComsumerApplication {
  4. public static void main(String[] args) {
  5. SpringApplication.run(EmployComsumerApplication.class,args);
  6. }
  7. }

修改yml文件

  1. eureka:
  2. client:
  3. service-url:
  4. #单机配置:http://localhost:8211/eureka
  5. defaultZone: http://registry8212:8212/eureka/,http://registry8213:8213/eureka/,http://registry8211:8211/eureka/
  6. register-with-eureka: false

此时访问消费者 就能够完成消费者 调用 服务端服务 的调用了

服务集群搭建

为了介绍下面的resttemplate+ribbon 和feign负载均衡,需要将服务作集群搭建。

基本架构是,每个服务访问自己独立的数据库,数据上构造一定的差异,这样方便我们测试负载均衡。

执行Employ-cluster.sql文件中的sql

创建三个不同的库,同样的表。然后插入不同的数据。

拷贝microservicecloud-employproviderwithregistry 三份

分别为microservicecloud-employ-provider-8911 microservicecloud-employ-provider-8912 microservicecloud-employ-provider-8913

具体修改内容见代码。

创建microservicecloud-employ-comsumer-robbin 模块

1.修改pom文件

  1. <!-- 添加 ribbon依赖-->
  2. <dependency>
  3. <groupId>org.springframework.cloud</groupId>
  4. <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.springframework.cloud</groupId>
  8. <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
  9. </dependency>

修改启动类

  1. @SpringBootApplication
  2. @EnableDiscoveryClient
  3. //指定某个服务用某种负载均衡算法
  4. @RibbonClient(name = "EMPLOYSERVICE",configuration = MyRules.class)
  5. public class EmployComsumerApplication {
  6. public static void main(String[] args) {
  7. SpringApplication.run(EmployComsumerApplication.class,args);
  8. }
  9. }

com.styz.rules.MyRules

  1. @Configuration
  2. public class MyRules {
  3. @Bean
  4. @Primary
  5. public IRule getRobbinRule(){
  6. return new RandomRule();
  7. }
  8. }

新建自定义负载均衡算法

com.styz.com.styz.com.styz.microservice.robbin.CountRobbinRule

  1. public class CountRobbinRule implements IRule {
  2. private ILoadBalancer loadBalancer;
  3. private AtomicInteger count = new AtomicInteger(0);
  4. private AtomicInteger serverIndex = new AtomicInteger(0);
  5. @Override
  6. public Server choose(Object o) {
  7. List<Server> allServers = loadBalancer.getAllServers();
  8. while (true){
  9. if(count.get() > 5){
  10. if(serverIndex.incrementAndGet() > allServers.size()){
  11. serverIndex.set(serverIndex.get()%allServers.size());
  12. }
  13. count.set(0);
  14. }else {
  15. count.incrementAndGet();
  16. return allServers.get(serverIndex.get());
  17. }
  18. }
  19. }
  20. @Override
  21. public void setLoadBalancer(ILoadBalancer iLoadBalancer) {
  22. loadBalancer = iLoadBalancer;
  23. }
  24. @Override
  25. public ILoadBalancer getLoadBalancer() {
  26. return loadBalancer;
  27. }
  28. }

修改配置文件类com.styz.com.styz.com.styz.microservice.config.ConsummerConfigBean

  1. @Configuration
  2. public class ConsummerConfigBean {
  3. /**
  4. * @LoadBalanced 注解会使用robbin负载均横算法。默认是轮训,如需修改得显示声明对应的算法。
  5. * 如果没有声明,默认就是轮训
  6. * robbin 提供7种轮训算法,我们可以手动扩展实现负载均衡算法。
  7. */
  8. @Bean
  9. @LoadBalanced
  10. public RestTemplate getRestTemplate(){
  11. RestTemplate restTemplate = new RestTemplate();
  12. return restTemplate;
  13. }
  14. }

启动注册中心,启动服务提供者集群,启动消费者,访问http://localhost:7111/consummer/getById/1 查看负载均衡情况。

引入Feign负载均衡

RestTemplate+robbin是基于微服务名称封装httpclient的方式完成的服务调用。

而Feign是在此基础上又进行了一次封装,使得消费端可以通过注解+接口的方式

用接口的方式完成服务的调用,有点类似于Dubbo中接口调用一样。只是底层实现不一样,

Dubbo是RPC,而Feign是http的Restful调用。

创建microservicecloud-employ-consummer-feign模块

修改pom文件添加Feign支持

  1. <dependencies>
  2. <dependency>
  3. <groupId>com.com.styz.microservicecloud</groupId>
  4. <artifactId>microservicecloud-api</artifactId>
  5. <version>${project.version}</version>
  6. </dependency>
  7. <dependency>
  8. <groupId>org.springframework.boot</groupId>
  9. <artifactId>spring-boot-starter</artifactId>
  10. </dependency>
  11. <dependency>
  12. <groupId>org.springframework.boot</groupId>
  13. <artifactId>spring-boot-starter-web</artifactId>
  14. </dependency>
  15. <dependency>
  16. <groupId>org.springframework.boot</groupId>
  17. <artifactId>spring-boot-devtools</artifactId>
  18. </dependency>
  19. <dependency>
  20. <groupId>org.springframework.cloud</groupId>
  21. <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
  22. </dependency>
  23. <dependency>
  24. <groupId>org.springframework.cloud</groupId>
  25. <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
  26. </dependency>
  27. <dependency>
  28. <groupId>org.springframework.cloud</groupId>
  29. <artifactId>spring-cloud-starter-openfeign</artifactId>
  30. </dependency>
  31. </dependencies>

2.修改microservicecloud-api 添加Feign接口com.styz.microservicecloud.service.EmployClientService


  1. @FeignClient(value = "EMPLOYSERVICE")
  2. public interface EmployClientService {
  3. //注意此时的url是服务端的全路径,不是客户端哦
  4. @RequestMapping(value = "/employ/getAllEmployes",method = RequestMethod.POST)
  5. public List<Employ> getAllEmployes();
  6. @RequestMapping(value = "/employ/getEmployById/{id}",method = RequestMethod.POST)
  7. public Employ getEmployById(@PathVariable("id")long id);
  8. }

修改com.styz.com.styz.com.styz.microservice.controller.EmployConsumerController

  1. @RestController
  2. @RequestMapping("/comsummer")
  3. public class EmployConsumerController {
  4. //EmployClientService 为Feign接口
  5. @Autowired
  6. private EmployClientService clientService;
  7. @RequestMapping("/getById/{id}")
  8. public Employ getEmployById(@PathVariable("id") long id){
  9. return clientService.getEmployById(id);
  10. }
  11. @RequestMapping("/getAllEmployes")
  12. public List<Employ> getAllEmployes(){
  13. return clientService.getAllEmployes();
  14. }
  15. }

修改启动类com.styz.com.styz.com.styz.microservice.EmployComsumerApplication

  1. @SpringBootApplication
  2. @EnableDiscoveryClient
  3. //注意EnableFeignClients 一定要扫描到@FeignClient的包否则会报错
  4. @EnableFeignClients(basePackages = "com.styz.microservicecloud.service")
  5. public class EmployComsumerApplication {
  6. public static void main(String[] args) {
  7. SpringApplication.run(EmployComsumerApplication.class,args);
  8. }
  9. }

此时再次访问http://localhost:7111/consummer/getById/1 查看负载均衡情况

添加熔断Hystrix支持

Hystrix是什么?请自行百度。

新建microservicecloud-employ-consummer-hystrix 模块

修改pom文件

  1. <dependencies>
  2. <dependency>
  3. <groupId>com.com.styz.microservicecloud</groupId>
  4. <artifactId>microservicecloud-api</artifactId>
  5. <version>${project.version}</version>
  6. </dependency>
  7. <dependency>
  8. <groupId>org.springframework.boot</groupId>
  9. <artifactId>spring-boot-starter</artifactId>
  10. </dependency>
  11. <dependency>
  12. <groupId>org.springframework.boot</groupId>
  13. <artifactId>spring-boot-starter-web</artifactId>
  14. </dependency>
  15. <dependency>
  16. <groupId>org.springframework.boot</groupId>
  17. <artifactId>spring-boot-devtools</artifactId>
  18. </dependency>
  19. <dependency>
  20. <groupId>org.springframework.cloud</groupId>
  21. <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
  22. </dependency>
  23. <dependency>
  24. <groupId>org.springframework.cloud</groupId>
  25. <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
  26. </dependency>
  27. <dependency>
  28. <groupId>org.springframework.cloud</groupId>
  29. <artifactId>spring-cloud-starter-openfeign</artifactId>
  30. </dependency>
  31. <dependency>
  32. <groupId>org.springframework.cloud</groupId>
  33. <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
  34. </dependency>
  35. <dependency>
  36. <groupId>org.projectlombok</groupId>
  37. <artifactId>lombok</artifactId>
  38. </dependency>
  39. </dependencies>

修改启动类添加

  1. @SpringBootApplication
  2. @EnableDiscoveryClient
  3. //注意EnableFeignClients 一定要扫描到@FeignClient的包否则会报错
  4. @EnableFeignClients(basePackages = "com.styz.microservicecloud.service")
  5. //添加熔断机制
  6. @EnableHystrix
  7. @ComponentScan("com.styz")
  8. public class EmployComsumerApplication {
  9. public static void main(String[] args) {
  10. SpringApplication.run(EmployComsumerApplication.class,args);
  11. }
  12. }

修改controller 添加@HystrixCommand,

一般情况下熔断一般实现在服务提供端,我这里只是demo就实现在消费端了。

@HystrixCommand能捕获异常可以根据异常不同,进行不同的熔断操作。

  1. @RestController
  2. @RequestMapping("/comsummer")
  3. public class EmployConsumerController {
  4. @Autowired
  5. private EmployClientService clientService;
  6. @RequestMapping("/getById/{id}")
  7. @HystrixCommand(fallbackMethod = "processEmployException")
  8. public Employ getEmployById(@PathVariable("id") long id){
  9. Employ employ = clientService.getEmployById(id);
  10. if(null == employ){
  11. throw new RuntimeException("未找到对应ID的员工!");
  12. }
  13. return employ;
  14. }
  15. /**
  16. * 这个方法可以写在服务端,也可以写在消费端,如果异常导致的最好写在服务端,如果非异常,可以实现在消费端
  17. * 方法写在服务端叫熔断,写在消费端叫降级。
  18. * HystrixCommand 注解能实现的熔断,但是缺点非常明显,容易导致方法膨胀:也就是每个方法都需要写一个异常方法
  19. * 方法会非常多,不便与维护。
  20. *
  21. * @param id
  22. * @return
  23. */
  24. public Employ processEmployException(@PathVariable("id") long id){
  25. Employ employ = new Employ();
  26. employ.setId(id);
  27. employ.setName("未找到对应ID的员工!");
  28. return employ;
  29. }
  30. @RequestMapping("/getAllEmployes")
  31. public List<Employ> getAllEmployes(){
  32. return clientService.getAllEmployes();
  33. }
  34. }

@HystrixCommand 业务代码耦合严重,方法容易膨胀,所以有了Fegin熔断机制

可以在接口上面实现熔断,从而解藕

修改com.styz.microservicecloud.service.EmployClientService


  1. /**
  2. * 服务降级处理:
  3. * 1.添加fallbackFactory 或者Fallback类
  4. * 2.开启服务降级:
  5. * feign:
  6. * hystrix:
  7. * enabled: true
  8. * 注意fallbackFactory类或者Fallback类要能被扫描到。否则不会生效。
  9. */
  10. @FeignClient(value = "EMPLOYSERVICE",fallbackFactory = EmployClientServiceFallbackFactory.class)
  11. public interface EmployClientService {
  12. //注意此时的url是服务端的全路径,不是客户端哦
  13. @RequestMapping(value = "/employ/getAllEmployes",method = RequestMethod.POST)
  14. public List<Employ> getAllEmployes();
  15. @RequestMapping(value = "/employ/getEmployById/{id}",method = RequestMethod.POST)
  16. public Employ getEmployById(@PathVariable("id")long id);
  17. }
  1. @Component
  2. public class EmployClientServiceFallbackFactory implements InitializingBean,FallbackFactory<EmployClientService> {
  3. @Override
  4. public void afterPropertiesSet() throws Exception {
  5. }
  6. public static class EmployClientServiceFallback implements EmployClientService{
  7. @Override
  8. public List<Employ> getAllEmployes() {
  9. ArrayList<Employ> employs = new ArrayList<>();
  10. employs.add(new Employ().setName("********暂停服务*****"));
  11. System.out.println("*************暂停服务****************");
  12. return employs;
  13. }
  14. @Override
  15. public Employ getEmployById(long id) {
  16. return new Employ(id,"该ID不存在",0L,"");
  17. }
  18. }
  19. @Override
  20. public EmployClientService create(Throwable throwable) {
  21. return new EmployClientServiceFallback();
  22. }
  23. }

开启Fegin降级机制

  1. feign:
  2. hystrix:
  3. enabled: true

此时称之为Feign+fallback 服务降级

何谓服务降级:简单的说就是当整个系统资源不够用时,为了满足某些服务依然可用,就需要忍痛将其他服务停掉,将系统资源释放

用以支持其他服务。此时停掉的服务不能影响整个系统的使用,就需要在消费端在访问不到服务的情况下,将服务进行降级处理。

启动消费者测试一下服务的熔断和降级看看。

添加监控HystrixDashboard支持

创建microservicecloud-employ-consummer-hystrixDashboard模块

修改pom文件

  1. <dependencies>
  2. <dependency>
  3. <groupId>com.com.styz.microservicecloud</groupId>
  4. <artifactId>microservicecloud-api</artifactId>
  5. <version>${project.version}</version>
  6. </dependency>
  7. <dependency>
  8. <groupId>org.springframework.boot</groupId>
  9. <artifactId>spring-boot-starter</artifactId>
  10. </dependency>
  11. <dependency>
  12. <groupId>org.springframework.boot</groupId>
  13. <artifactId>spring-boot-starter-web</artifactId>
  14. </dependency>
  15. <dependency>
  16. <groupId>org.springframework.boot</groupId>
  17. <artifactId>spring-boot-devtools</artifactId>
  18. </dependency>
  19. <dependency>
  20. <groupId>org.springframework.cloud</groupId>
  21. <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
  22. </dependency>
  23. <dependency>
  24. <groupId>org.springframework.cloud</groupId>
  25. <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
  26. </dependency>
  27. <dependency>
  28. <groupId>org.springframework.cloud</groupId>
  29. <artifactId>spring-cloud-starter-openfeign</artifactId>
  30. </dependency>
  31. <dependency>
  32. <groupId>org.springframework.cloud</groupId>
  33. <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
  34. </dependency>
  35. <dependency>
  36. <groupId>org.springframework.cloud</groupId>
  37. <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
  38. </dependency>
  39. <dependency>
  40. <groupId>org.springframework.boot</groupId>
  41. <artifactId>spring-boot-starter-actuator</artifactId>
  42. </dependency>
  43. <dependency>
  44. <groupId>org.projectlombok</groupId>
  45. <artifactId>lombok</artifactId>
  46. </dependency>
  47. </dependencies>
  48. <build>
  49. <finalName>${project.artifactId}</finalName>
  50. <resources>
  51. <resource>
  52. <directory>src/main/resource</directory>
  53. <filtering>true</filtering>
  54. </resource>
  55. </resources>
  56. <plugins>
  57. <!--添加actor/info信息的描述-->
  58. <plugin>
  59. <groupId>org.apache.maven.plugins</groupId>
  60. <artifactId>maven-resources-plugin</artifactId>
  61. <configuration>
  62. <delimiters>
  63. <delimiter>$</delimiter>
  64. </delimiters>
  65. </configuration>
  66. </plugin>
  67. </plugins>
  68. </build>

修改启动类:

  1. @SpringBootApplication
  2. @EnableDiscoveryClient
  3. //注意EnableFeignClients 一定要扫描到@FeignClient的包否则会报错
  4. @EnableFeignClients(basePackages = "com.styz.microservicecloud.service")
  5. //添加熔断机制
  6. @EnableHystrix
  7. @ComponentScan("com.styz")
  8. //添加服务监控 1.服务端要添加对应的包spring-boot-starter-actuator
  9. @EnableHystrixDashboard
  10. public class EmployComsumerApplication {
  11. public static void main(String[] args) {
  12. SpringApplication.run(EmployComsumerApplication.class,args);
  13. }
  14. }

hystrix.stream

springboot2.0中hystrix.stream url出现404错误问题解决办法1

添加配置类com.styz.com.styz.com.styz.microservice.config.HystrixConfig

  1. @Configuration
  2. public class HystrixConfig {
  3. @Bean
  4. public HystrixMetricsStreamServlet hystrixMetricsStreamServlet(){
  5. return new HystrixMetricsStreamServlet();
  6. }
  7. @Bean
  8. public ServletRegistrationBean registration(HystrixMetricsStreamServlet servlet){
  9. ServletRegistrationBean registrationBean = new ServletRegistrationBean();
  10. registrationBean.setServlet(servlet);
  11. //是否启用该registrationBean
  12. registrationBean.setEnabled(true);
  13. registrationBean.addUrlMappings("/hystrix.stream");
  14. return registrationBean;
  15. }
  16. }

修改yml文件

  1. #需要暴露的url:
  2. #这里暴露了/actuator/hystrix.stream,/actuator/info
  3. management:
  4. endpoints:
  5. web:
  6. exposure:
  7. include:
  8. - hystrix.stream
  9. - info
  10. # 添加服务Info信息
  11. info:
  12. app.name: ${eureka.instance.instance-id}
  13. app.describution: 带熔断监控器的消费者
  14. company.name: com.com.styz
  15. author.name: liuy
  16. build.artifactId: $project.artifactId$
  17. build.version: $project.version$

访问 http://localhost:7112/hystrix 页面,出现豪猪图片表示成功

访问 http://localhost:7112/hystrix/hystrix.stream 出现ping 字眼表示成功

http://localhost:7112/hystrix 这个页面如何使用,请自行百度吧。

前面使用的/hystrix.stream端点监控单个微服务。然而在使用微服务架构的应用系统一般会包含多个微服务,每个微服务通常都会部署多个实例。如果每次只能查看单个实例的监控数据,就必须在Hystrix Dashboard上切换想要监控的地址,这显然很不方便。

Turbine简介

Turbine是一个聚合Hystrix监控数据的工具,它可将所有相关/hystrix.stream端点的数据聚合到一个组合的/turbine.stream中,从而让集群的监控更加方便

使用Turbine监控多个微服务

创建microservicecloud-employ-consummer-hystrixDashborad-turbine

修改pom文件

  1. <!--添加Turbine依赖-->
  2. <dependency>
  3. <groupId>org.springframework.cloud</groupId>
  4. <artifactId>spring-cloud-starter-netflix-turbine</artifactId>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.springframework.cloud</groupId>
  8. <artifactId>spring-cloud-netflix-turbine</artifactId>
  9. </dependency>

修改启动类添加@EnableTurbine注解

  1. @SpringBootApplication
  2. @EnableDiscoveryClient
  3. //注意EnableFeignClients 一定要扫描到@FeignClient的包否则会报错
  4. @EnableFeignClients(basePackages = "com.styz.microservicecloud.service")
  5. //添加熔断机制
  6. @EnableHystrix
  7. @ComponentScan("com.styz")
  8. //添加服务监控 1.服务端要添加对应的包spring-boot-starter-actuator
  9. @EnableHystrixDashboard
  10. @EnableTurbine
  11. public class EmployConsummerTurbineApplication {
  12. public static void main(String[] args) {
  13. SpringApplication.run(EmployConsummerTurbineApplication.class,args);
  14. }
  15. }

添加turbine配置

  1. turbine:
  2. # app-config表示待监测的服务名称
  3. app-config: EmployComsummer-HystrixDashboard,EmployComsummer-HystrixDashboard-Turbine
  4. aggregator:
  5. cluster-config: default
  6. cluster-name-expression: new String("default")

turbine.appConfig :配置Eureka中的serviceId列表,表明监控哪些服务

turbine.aggregator.clusterConfig :指定聚合哪些集群,多个使用","分割,默认为default。可使用http://.../turbine.stream?cluster={clusterConfig之一}访问

turbine.clusterNameExpression :

  1. clusterNameExpression指定集群名称,默认表达式appName;此时:turbine.aggregator.clusterConfig需要配置想要监控的应用名称;
  2. 当clusterNameExpression: default时,turbine.aggregator.clusterConfig可以不写,因为默认就是default;
  3. 当clusterNameExpression: metadata['cluster']时,假设想要监控的应用配置了eureka.instance.metadata-map.cluster: ABC,则需要配置,同时turbine.aggregator.clusterConfig: ABC

测试

启动microservicecloud-employ-consummer-hystrixDashboard 和microservicecloud-employ-consummer-hystrixDashborad-turbine

访问http://localhost:7113/hystrix,监控http://localhost:7113/turbine.stream 后然后分别访问

http://localhost:7112/comsummer/getById/1 和http://localhost:7113/comsummer/getById/1

查看监控面板的变化。

添加网关Zuul支持

创建microservicecloud-gateway-zuul

修改pom文件

  1. <dependencies>
  2. <dependency>
  3. <groupId>org.springframework.cloud</groupId>
  4. <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.springframework.cloud</groupId>
  8. <artifactId>spring-cloud-starter-config</artifactId>
  9. </dependency>
  10. <dependency>
  11. <groupId>org.springframework.cloud</groupId>
  12. <artifactId>spring-cloud-starter</artifactId>
  13. </dependency>
  14. <dependency>
  15. <groupId>org.springframework.cloud</groupId>
  16. <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
  17. </dependency>
  18. <dependency>
  19. <groupId>org.springframework.boot</groupId>
  20. <artifactId>spring-boot-actuator</artifactId>
  21. </dependency>
  22. </dependencies>

配置:

  1. eureka:
  2. client:
  3. service-url:
  4. #单机配置:http://localhost:8211/eureka
  5. defaultZone: http://registry8212:8212/eureka/,http://registry8213:8213/eureka/,http://registry8211:8211/eureka/
  6. register-with-eureka: true
  7. fetch-registry: true
  8. instance:
  9. instance-id: GateWay
  10. prefer-ip-address: true
  11. zuul:
  12. ignoredServices: '*'
  13. host:
  14. connect-timeout-millis: 20000
  15. socket-timeout-millis: 20000
  16. routes:
  17. employservice:
  18. path: /employ/**
  19. serviceId: employservice
  20. stripPrefix: false
  21. sensitiveHeaders:
  22. employcomsummer-hystrix:
  23. path: /consummer/**
  24. serviceId: employcomsummer-hystrix
  25. stripPrefix: false
  26. sensitiveHeaders:
  27. employcomsummer-hystrixdashboard:
  28. path: /dashboard/**
  29. serviceId: employcomsummer-hystrixdashboard
  30. stripPrefix: false
  31. sensitiveHeaders:
  32. baidu:
  33. path: /baidu/**
  34. url: http://www.baidu.com/

启动类添加

  1. @SpringBootApplication
  2. @EnableZuulProxy
  3. @EnableDiscoveryClient
  4. public class GatewayApplication {
  5. public static void main(String[] args) {
  6. SpringApplication.run(GatewayApplication.class,args);
  7. }
  8. }

添加配置服务Config支持

新建microservicecloud-config模块

修改pom文件

  1. <dependencies>
  2. <dependency>
  3. <groupId>org.springframework.cloud</groupId>
  4. <artifactId>spring-cloud-config-server</artifactId>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.springframework.boot</groupId>
  8. <artifactId>spring-boot-starter</artifactId>
  9. </dependency>
  10. <dependency>
  11. <groupId>org.springframework.boot</groupId>
  12. <artifactId>spring-boot-starter-web</artifactId>
  13. </dependency>
  14. </dependencies>

创建com.styz.microservicecloud.ConfigServerApplication

  1. @SpringBootApplication
  2. @EnableConfigServer
  3. public class ConfigServerApplication {
  4. public static void main(String[] args) {
  5. SpringApplication.run(ConfigServerApplication.class,args);
  6. }
  7. }

修改配置文件

  1. spring:
  2. cloud:
  3. config:
  4. server:
  5. native:
  6. search-locations: classpath:/config
  7. # 本地模式
  8. profiles:
  9. active: native
  10. server:
  11. port: 8888

此配置意思是config配置服务器扫描服务所在的config目录。将config目录下

的配置文件发不成restful接口。

启动com.styz.microservicecloud.ConfigServerApplication 然后

访问http://localhost:8888/config/dev 就能访问到application-dev.yml配置。

访问http://localhost:8888/employservice/default 就能访问到employsevice配置。

修改服务提供者

修改microservicecloud-employ-provider-8911 让其加载config服务器上的配置

1.删除原来的application.yml

2.添加依赖spring-cloud-starter-config 其实原来就有。

  1. <dependency>
  2. <groupId>org.springframework.cloud</groupId>
  3. <artifactId>spring-cloud-starter-config</artifactId>
  4. </dependency>

3.修改bootstrap.yml 添加如下内容

  1. spring:
  2. application:
  3. name: EmployService
  4. cloud:
  5. config:
  6. uri: http://config:8888
  7. fail-fast: true

spring.cloud.config.url 配置的就是配置服务的地址。

重启服务端microservicecloud-employ-provider-8911 测试一下是否正常

采用spring.cloud.config.url 这种方式指定url的方式直接连接,有明显缺陷,

当配置服务器挂掉,无法加载远程配置。就有了将config服务器服务化,注册到

Eureka,利用服务发现的方式去找服务的地址,从而实现config地址动态变化,尽管

config服务器发生变化,服务端也无需在修改对应的url。同时config配置服务器可以做

集群注册到Eureka,从而也可避免单点故障。

配置中心config把配置放置到git仓库

之前配置放在本地了,现在将配置迁移到git仓库,好处是config服务做集群的时候可以统一从仓库拉取配置,

自己不需要维护配置文件。

创建存放配置的git目录

在microservicecloud文件夹下创建microservicecloud-config-dir目录

将配置文件放入此文件,提交github。

新建microservicecloud-config-git 模块

1.修改pom文件

  1. <dependencies>
  2. <dependency>
  3. <groupId>org.springframework.boot</groupId>
  4. <artifactId>spring-boot-starter-web</artifactId>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.springframework.boot</groupId>
  8. <artifactId>spring-boot-starter</artifactId>
  9. </dependency>
  10. <dependency>
  11. <groupId>org.springframework.cloud</groupId>
  12. <artifactId>spring-cloud-config-server</artifactId>
  13. </dependency>
  14. <dependency>
  15. <groupId>org.springframework.cloud</groupId>
  16. <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
  17. </dependency>
  18. <dependency>
  19. <groupId>org.springframework.boot</groupId>
  20. <artifactId>spring-boot-actuator</artifactId>
  21. </dependency>
  22. </dependencies>

2.新建类com.styz.microservicecloud.GItConfigServerApplication

  1. @EnableConfigServer
  2. public class GItConfigServerApplication {
  3. public static void main(String[] args) {
  4. SpringApplication.run(GItConfigServerApplication.class,args);
  5. }
  6. }

3.修改yml


  1. spring:
  2. application:
  3. name: GitConfigServer
  4. cloud:
  5. config:
  6. # label 表示是哪个分支
  7. label: master
  8. server:
  9. git:
  10. # git用户密码私有仓库必填
  11. username:
  12. password:
  13. # uri 是git的地址
  14. uri: https://github.com/liuyong520/microservicecloud
  15. # search-paths 搜索git仓库哪个目录,相对地址
  16. search-paths: microservicecloud-config-dir
  17. eureka:
  18. client:
  19. register-with-eureka: true
  20. service-url:
  21. defaultZone: http://registry8212:8212/eureka/,http://registry8213:8213/eureka/,http://registry8211:8211/eureka/
  22. instance:
  23. instance-id: GitConfigServer
  24. prefer-ip-address: true
  25. server:
  26. port: 8888

server端就此改造完了

测试一下

访问http://localhost:8888/config/dev 就能访问到application-dev.yml配置。

访问http://localhost:8888/employservice/default 就能访问到employsevice配置。

修改microservicecloud-employ-provider-8911

采用服务发现的方式连接configsever。

  1. spring:
  2. application:
  3. name: EmployService
  4. cloud:
  5. config:
  6. name: EmployService #指定配置文件名称
  7. profile: default
  8. label: master
  9. discovery:
  10. enabled: true
  11. service-id: GitConfigServer #configserver服务

重启服务端看看是否正常启动。

添加链路跟踪

何谓链路跟踪?

在分布式系统中往往一次简单的请求,往往涉及到一系列的服务调用,服务A调用服务B,服务B调用服务C。这样

的服务链上如果某个服务发生故障,无法快速定外到故障点,从而无法快速定位问题。而链路

跟踪是就是跟踪整个服务之间的调用链,监控每个服务间的调用情况,以备在调用出现问题时,能快速定位问题。

zipKin 简介

Zipkin是一种分布式跟踪系统。它有助于收集解决服务体系结构中的延迟问题所需的计时数据。功能包括收集和查找此数据。

如果日志文件中有跟踪ID,则可以直接跳转到该文件。否则,您可以根据服务,操作名称,标签和持续时间等属性进行查询。将为您总结一些有趣的数据,例如在服务中花费的时间百分比,以及操作是否失败

Zipkin UI还提供了一个依赖关系图,显示了每个应用程序通过的跟踪请求数。这有助于识别聚合行为,包括错误路径或对已弃用服务的调用。

zipKin环境搭建

1.docker环境下:

  1. docker run --name zipkin -d -p 9411:9411 openzipkin/zipkin

2.物理机

  1. curl -sSL https://zipkin.io/quickstart.sh | bash -s
  2. java -jar zipkin.jar

访问http://localhost:9411/ 出现zipkin UI界面

为了 演示一下链路跟踪需要搭建一个调用链环境,我这里用一个消费端和服务端来演示

修改服务提供者

1.新建microservicecloud-employ-provider-8911-sleuth

改造一下microservicecloud-employ-provider-8911

修改pom

  1. <dependency>
  2. <groupId>org.springframework.cloud</groupId>
  3. <artifactId>spring-cloud-starter-sleuth</artifactId>
  4. </dependency>
  5. <dependency>
  6. <groupId>org.springframework.cloud</groupId>
  7. <artifactId>spring-cloud-starter-zipkin</artifactId>
  8. </dependency>

修改yml文件

  1. spring:
  2. application:
  3. name: EmployService
  4. #添加链路跟踪
  5. sleuth:
  6. web:
  7. client:
  8. enabled: true
  9. sampler:
  10. probability: 1.0
  11. zipkin:
  12. base-url: http://k8s-n3:9411/

至此服务端改造完成

修改消费者

1.新建microservicecloud-employ-consummer-hystrix-sleuth模块

改造一下microservicecloud-employ-consummer-hystrix

修改pom文件

  1. <dependency>
  2. <groupId>org.springframework.cloud</groupId>
  3. <artifactId>spring-cloud-starter-sleuth</artifactId>
  4. </dependency>
  5. <dependency>
  6. <groupId>org.springframework.cloud</groupId>
  7. <artifactId>spring-cloud-starter-zipkin</artifactId>
  8. </dependency>

然后修改一下yml文件

  1. server:
  2. port: 7115
  3. spring:
  4. application:
  5. name: EmployComsummer-Hystrix
  6. devtools:
  7. restart:
  8. enabled: true
  9. sleuth:
  10. web:
  11. client:
  12. enabled: true
  13. sampler:
  14. probability: 1.0 #采样比例 1表示100%全部采样
  15. zipkin:
  16. base-url: http://k8s-n3:9411/

消费端完成

启动服务端和消费端,访问http://localhost:7115/consummer/getById/1 调用一下消费者,

然后去http://localhost:9411/zipkin/ 查看一下链路跟踪情况。

简单说一下链路跟踪的原理:针对给个服务的调用,都进行来埋点,消息的发送时刻以及消息的接收,

都会被记录,以及包括服务名称,方法名称都被埋点探针记录下来,每次调用链上有唯一的tracId,这个是

全局唯一的,然后用spanId区分是调用链上的哪个服务的哪个方法。以上数据的采集是通过httpReport方式提交的

这种方式优点是简单直接,缺点是 1.网络问题:导致数据采集丢失 2。给zipkin带上访问上的压力量大可以压蹦zipkin

所以要改造一下:用消息队列进行解藕。就有了下面的sleuth+zipkin+rabbitmq方式,当然消息队列可以换成kafka也没有问题。

链路跟踪之sleuth+zipKin+rabbitmq

rabbitMq环境搭建

我这里用的是docker环境,所以直接贴出来docker下搭建过程。

拉取官方镜像,镜像地址:https://hub.docker.com/_/rabbitmq/

拉取镜像:docker pull rabbitmq,如需要管理界面:docker pull rabbitmq:management

执行指令启动RabbitMQ

无管理界面:

  1. docker run --localhost rabbit-host --name my_rabbit -d -p 5672:5672 rabbitmq

有管理界面:

  1. docker run --localhost rabbit-host --name my_rabbit -d -p 5672:5672 -p 15672:15672 rabbitmq:management

账号:guest 密码:guest

调整之前的消费者和服务者

修改pom文件

  1. <dependency>
  2. <groupId>org.springframework.cloud</groupId>
  3. <artifactId>spring-cloud-starter-stream-rabbit</artifactId>
  4. </dependency>

修改yml文件

  1. spring
  2. sleuth:
  3. web:
  4. client:
  5. enabled: true
  6. sampler:
  7. probability: 1.0
  8. zipkin:
  9. sender:
  10. type: rabbit
  11. rabbitmq:
  12. password: guest
  13. username: guest
  14. host: k8s-n3
  15. port: 5672
  16. virtual-host: /

修改zipkin服务端

  1. docker run -d -p9411:9411 -e "RABBIT_ADDRESSES=rabbithost:5672" openzipkin/zipkin

如果你的rabbitMq用户名密码不是guest需要指定环境变量。

结果展示



详细源码参见GitHub 地址:https://github.com/liuyong520/microservicecloud

跟着我一步一步的搭建一个基于springcloud的微服务实例的更多相关文章

  1. 利用SpringCloud搭建一个最简单的微服务框架

    http://blog.csdn.net/caicongyang/article/details/52974406 1.微服务 微服务主要包含服务注册,服务发现,服务路由,服务配置,服务熔断,服务降级 ...

  2. 基于SpringCloud的微服务架构实战案例项目,以一个简单的购物流程为示例

    QuickStart 基于SpringCloud体系实现,简单购物流程实现,满足基本功能:注册.登录.商品列表展示.商品详情展示.订单创建.详情查看.订单支付.库存更新等等. 每个业务服务采用独立的M ...

  3. 一个不错的架构图:基于SpringCloud的微服务项目

    https://github.com/hanlin5566/HJ-MicroService

  4. 通过Dapr实现一个简单的基于.net的微服务电商系统(四)——一步一步教你如何撸Dapr之订阅发布

    之前的章节我们介绍了如何通过dapr发起一个服务调用,相信看过前几章的小伙伴已经对dapr有一个基本的了解了,今天我们来聊一聊dapr的另外一个功能--订阅发布 目录:一.通过Dapr实现一个简单的基 ...

  5. 通过Dapr实现一个简单的基于.net的微服务电商系统(十一)——一步一步教你如何撸Dapr之自动扩/缩容

    上一篇我们讲到了dapr提供的bindings,通过绑定可以让我们的程序轻装上阵,在极端情况下几乎不需要集成任何sdk,仅需要通过httpclient+text.json即可完成对外部组件的调用,这样 ...

  6. 通过Dapr实现一个简单的基于.net的微服务电商系统(三)——一步一步教你如何撸Dapr

    目录:一.通过Dapr实现一个简单的基于.net的微服务电商系统 二.通过Dapr实现一个简单的基于.net的微服务电商系统(二)--通讯框架讲解 三.通过Dapr实现一个简单的基于.net的微服务电 ...

  7. 通过Dapr实现一个简单的基于.net的微服务电商系统(五)——一步一步教你如何撸Dapr之状态管理

    状态管理和上一章的订阅发布都算是Dapr相较于其他服务网格框架来讲提供的比较特异性的内容,今天我们来讲讲状态管理. 目录:一.通过Dapr实现一个简单的基于.net的微服务电商系统 二.通过Dapr实 ...

  8. 通过Dapr实现一个简单的基于.net的微服务电商系统(六)——一步一步教你如何撸Dapr之Actor服务

    我个人认为Actor应该是Dapr里比较重头的部分也是Dapr一直在讲的所谓"stateful applications"真正具体的一个实现(个人认为),上一章讲到有状态服务可能很 ...

  9. 通过Dapr实现一个简单的基于.net的微服务电商系统(七)——一步一步教你如何撸Dapr之服务限流

    在一般的互联网应用中限流是一个比较常见的场景,也有很多常见的方式可以实现对应用的限流比如通过令牌桶通过滑动窗口等等方式都可以实现,也可以在整个请求流程中进行限流比如客户端限流就是在客户端通过随机数直接 ...

随机推荐

  1. oracle数据库可视化工具

    1.TreeSoft基于web网页方式,管理维护oracle数据,功能包括:SQL在线执行,数据在线维护管理,数据导出,数据交换同步等. 支持MySQL,Oracle,DB2,PostgreSQL,S ...

  2. Spark + sbt + IDEA + HelloWorld + MacOS

    构建项目步骤 首先要安装好scala.sbt.spark,并且要知道对应的版本 sbt版本可以在sbt命令行中使用sbtVersion查看 spark-shell可以知晓机器上spark以及对应的sc ...

  3. kubernetes资源调度

    kubernetes默认情况下创建pod调度是由kubernetes scheduler来管理的,但显然有时候还是需要人为介入.根据目前的kubernetes版本来说,有两种自定义资源调度的方式:No ...

  4. 【VS开发】MP4与H.264

    一.MP4格式基本概念 MP4格式对应标准MPEG-4标准(ISO/IEC14496) 二.MP4封装格式核心概念 1  MP4封装格式对应标准为 ISO/IEC 14496-12(信息技术 视听对象 ...

  5. OpenCV.学习OpenCV.pdf

    1.Pdf.P160(书.P129) “表5-1:平滑操作的各总类型” 的列名 看起来很模糊,现在先把尽可能看得清的字记录下来: 平滑类型 名称 支持 No 输入数据类型 输出数据类型 简要说明 2. ...

  6. MySQL的安装、配置与优化

    MySQL 安装配置 参考网址:https://www.runoob.com/linux/mysql-install-setup.html MySQL 是最流行的关系型数据库管理系统,由瑞典MySQL ...

  7. std::unique_lock与std::lock_guard分析

    背景 C++多线程编程中通常会对共享的数据进行写保护,以防止多线程在对共享数据成员进行读写时造成资源争抢,导致程序出现未定义或异常行为.通常的做法是在修改共享数据成员时进行加锁(mutex).在使用锁 ...

  8. [LuoguP2159][SHOI2009]舞会_动态规划_高精度_排列组合

    舞会 题目链接:https://www.luogu.org/problem/P2159 数据范围:略. 题解: 不会.... 看了题解觉得自己好傻逼啊

  9. redis主从复制初识

    一.作用 slave会通过被复制同步master上面的数据,形成数据副本 当master节点宕机时,slave可以升级为master节点承担写操作. 允许有一主多从,slave可以承担读操作,提高读性 ...

  10. javaSE总结(一)-java数据类型和运算符

    一.注释 (1)单行注释: // (2)多行注释:/*  */  (3)文档注释:/**  */ 二.标识符和关键字 (1)分隔符:分号; 花括号{} 方括号[] 圆括号() 空格 圆点(.)     ...