跟着我一步一步的搭建一个基于springcloud的微服务实例
Table of Contents generated with DocToc
- microservicecloud
- 插件推荐
- 建立父工程Microservicecloud
- Eureka注册中心搭建
- 单机模式
- 集群搭建
- 注册服务到注册中心
- 消费者调用
- 服务集群搭建
- 引入Feign负载均衡
- 添加熔断Hystrix支持
- 添加监控HystrixDashboard支持
- 添加网关Zuul支持
- 添加配置服务Config支持
- 配置中心config把配置放置到git仓库
- 添加链路跟踪
- 链路跟踪之sleuth+zipKin+rabbitmq
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文件
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.30</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<version>2.0.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.0</version>
</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>
<repository>
<id>repository.springframework.maven.release</id>
<name>Spring Framework Maven Release Repository</name>
<url>http://maven.springframework.org/milestone/</url>
</repository>
<repository>
<id>org.springframework</id>
<url> http://maven.springframework.org/snapshot</url>
</repository>
<repository>
<id>spring-milestone</id>
<name>Spring Maven MILESTONE Repository</name>
<url>http://repo.spring.io/libs-milestone</url>
</repository>
<repository>
<id>spring-release</id>
<name>Spring Maven RELEASE Repository</name>
<url>http://repo.spring.io/libs-release</url>
</repository>
</repositories>
搭建Employ员工服务
创建数据库
1.执行microserivcecloud-database中的Employ.sql文件创建员工服务需要用到的表
当然也可以自己考出来执行
use db;
SET STORAGE_ENGINE = InnoDB;
DROP TABLE IF EXISTS `employ`;
CREATE TABLE `employ` (
`id` bigint(20) NOT NULL COMMENT '员工编号',
`name` varchar(48) NOT NULL COMMENT '名字',
`departmentId` bigint(10) NOT NULL COMMENT '部门编号',
`datasourceId` varchar(64) NOT NULL COMMENT '数据存储位置',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
insert into employ(id,name,departmentId,datasourceId) values(1,"zhansan",1,DATABASE());
insert into employ(id,name,departmentId,datasourceId) values(2,"lisi",2,DATABASE());
insert into employ(id,name,departmentId,datasourceId) values(3,"wangwu",3,DATABASE());
insert into employ(id,name,departmentId,datasourceId) values(4,"maliu",4,DATABASE());
2.创建springboot+mybatis整合项目
2.1创建microservicecloud-api 子模块项目用于存放公共的接口和实体
修改pom.xml文件
<!--添加lombok依赖-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
2.2利用MyBatisCodeHelper-Pro生成mybatis的mapper接口和数据库实体到microservicecloud-api中
生成结果如下
com.styz.microservicecloud.entity.Employ #实体
com.styz.microservicecloud.mapper.EmployMapper #mapper接口
microservicecloud-api/src/main/resources/mapperxml/EmployMapper.xml #mapper.xml sql 文件
然后执行mvn install操作
2.3创建microservicecloud-employservice 模块
修改pom文件
<dependencies>
<dependency>
<groupId>com.com.styz.microservicecloud</groupId>
<artifactId>microservicecloud-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.1</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.0</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
</dependencies>
创建com.styz.microservicecloud包新建EmployServiceApplication启动类
@SpringBootApplication
@MapperScan("com.com.styz.microservicecloud.mapper")
public class EmployServiceApplication {
public static void main(String[] args) {
SpringApplication.run(EmployServiceApplication.class);
}
}
然后创建com.styz.com.styz.microserivcecloud.service.EmployService接口以及其实现类
public interface EmployService {
/**
* 获取所有员工
* @return
*/
public List<Employ> getAllEmployes();
/**
* 根据Id获取指定员工
* @param id
* @return
*/
public Employ getEmployById(long id);
}
@Service
public class EmployServiceImpl implements EmployService {
@Autowired
private EmployMapper employMapper;
public List<Employ> getAllEmployes() {
return employMapper.listAll();
}
public Employ getEmployById(long id) {
return employMapper.selectByPrimaryKey(id);
}
}
然后创建com.styz.com.styz.microserivcecloud.controller.EmployController
@RestController
@RequestMapping("/employ")
public class EmployController {
@Autowired
private EmployService employService;
@RequestMapping("/getAllEmployes")
public List<Employ> getAllEmployes(){
return employService.getAllEmployes();
}
@RequestMapping("/getEmployById/{id}")
public Employ getEmployById(@PathVariable("id")long id){
return employService.getEmployById(id);
}
}
添加配置文件
#应用程序使用的端口
server:
port: 8999
#mybatis相关配置
mybatis:
config-location: classpath:mybatis/mybatis.cfg.xml
type-alias-package: com.com.styz.microservicecloud.entity
mapper-locations:
- classpath*:mapperxml/*Mapper.xml
#数据源配置
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://k8s-n1:3307/db
username: root
password: 123456
dbcp2:
min-idle: 5
initial-size: 5
max-idle: 10
max-total: 20
max-wait-millis: 10
# 服务名称
application:
name: EmployService
mybatis/mybatis.cfg.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<!--二级缓存开启-->
<setting name="cacheEnabled" value="true"/>
</settings>
</configuration>
注意:@MapperScan("com.com.styz.microservicecloud.mapper")必须扫描到API模块里的mapper接口
2.5 自嗨一下
访问http://localhost:8999/employ/getAllEmployes 查看一下是否正常返回
自此单机服务已经整合完毕
创建消费者服务microservicecloud-employconsummer
1.新建模块microservicecloud-employconsummer修改pom文件
<dependencies>
<dependency>
<groupId>com.com.styz.microservicecloud</groupId>
<artifactId>microservicecloud-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</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>
</dependencies>
2.添加配置application.yml
server:
port: 8111
spring:
application:
name: EmployComsummer
devtools:
restart:
enabled: true
3.新建config配置类com.styz.com.styz.com.styz.microservice.config.ConsummerConfigBean
@Configuration
public class ConsummerConfigBean {
/**
* RestTemplate 封装了httpclient的实现能够简化我们对请求的访问
* @return
*/
@Bean
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}
4.创建消费者controller com.styz.com.styz.com.styz.microservice.controller.EmployConsumerController
@RestController
@RequestMapping("/comsummer")
public class EmployConsumerController {
//服务提供方的地址:http://localhost:8999/employ/getAllEmployes
public static final String EMPLOY_PROVIDE_URL="http://localhost:8999/employ";
@Autowired
private RestTemplate restTemplate;
@RequestMapping("/getById/{id}")
public Employ getEmployById(@PathVariable("id") long id){
return restTemplate.postForObject(EMPLOY_PROVIDE_URL+"/getEmployById/"+id,null,Employ.class);
}
@RequestMapping("/getAllEmployes")
public List<Employ> getAllEmployes(){
return restTemplate.postForObject(EMPLOY_PROVIDE_URL+"/getAllEmployes",null,List.class);
}
}
5.新建消费者启动类:com.styz.com.styz.com.styz.microservice.EmployComsumerApplication
@SpringBootApplication
public class EmployComsumerApplication {
public static void main(String[] args) {
SpringApplication.run(EmployComsumerApplication.class);
}
}
至此单体消费者实例已经完成。自嗨一下:访问http://localhost:8111/consummer/getById/1 看看能不能调用到服务端
提供的服务
Eureka注册中心搭建
Eureka主要的功能就是服务注册与发现。是Netflix公司下开源一款产品,功能比较单一
基于AP原则实现。cs架构模式实现,想要详细了Eureka可以百度。
单机模式
创建microservicecloud-registry-8211 模块
1.修改pom文件
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</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>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<finalName>${project.name}</finalName>
</configuration>
</plugin>
</plugins>
</build>
2.创建com.styz.com.styz.com.styz.microservice.RegistryApplication_8211 启动类
@SpringBootApplication
@EnableEurekaServer
public class RegistryApplication_8211 {
public static void main(String[] args) {
SpringApplication.run(RegistryApplication_8211.class,args);
}
}
3.配置文件
spring:
application:
name: registry-8211
eureka:
instance:
#euraka 服务器实例名称
#主机名字需要修改host文件
hostname: registry8211
client:
#false表示不向注册中心注册自己
register-with-eureka: false
#false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
fetch-registry: false
service-url:
#单机配置 http://${eureka.instance.hostname}:${server.port}/eureka
#集群环境搭建:http://registry8212:8212/eureka/,http://registry8213:8213/eureka/
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka
server:
port: 8211
单机注册中心已经完成 访问 http://registry8211:8211/ 就会出现注册中心的界面
集群搭建
修改microservicecloud-registry-8211 模块
1.只需要修改bootstrap.yml中的
defaultZone: http://registry8212:8212/eureka/,http://registry8213:8213/eureka/
拷贝microservicecloud-registry-8211 两份
microservicecloud-registry-8212 microservicecloud-registry-8213
同理修改
spring:
application:
name: registry-8212
eureka:
instance:
#euraka 服务器实例名称
hostname: registry8212
client:
#false表示不向注册中心注册自己
register-with-eureka: false
#false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
fetch-registry: false
service-url:
#单机配置 http://${eureka.instance.hostname}:${server.port}/eureka
#集群环境搭建
defaultZone: http://registry8211:8211/eureka/,http://registry8213:8213/eureka/
server:
port: 8212
spring:
application:
name: registry-8213
eureka:
instance:
#euraka 服务器实例名称
hostname: registry8213
client:
#false表示不向注册中心注册自己
register-with-eureka: false
#false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
fetch-registry: false
service-url:
#单机配置 http://${eureka.instance.hostname}:${server.port}/eureka
#集群环境搭建
defaultZone: http://registry8211:8211/eureka/,http://registry8212:8212/eureka/
server:
port: 8213
修改hosts文件
127.0.0.1 registry8213 registry8212 registry8211
至此集群模式搭建完毕,可以分别访问 http://registry8211:8211/ http://registry8212:8212/ http://registry8213:8213/
出现Eureka的界面表示成功。
注册服务到注册中心
新建microservicecloud-employproviderwithregistry
拷贝microserivicecloud-employservice中的代码和配置文件到microservicecloud-employproviderwithregistry 模块中
修改pom文件
<!--添加注册中心依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!--添加springboot监控依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
添加bootstrap.yml文件
#服务名称
spring:
application:
name: EmployService
eureka:
client:
service-url:
#单机配置:http://localhost:8211/eureka
defaultZone: http://registry8212:8212/eureka/,http://registry8213:8213/eureka/,http://registry8211:8211/eureka/
# 修改注册服务的名字
instance:
instance-id: EmployService-8999
# 防问路径可以显示IP地址
prefer-ip-address: true
# 添加服务Info信息
info:
app.name: EmployService-8999
app.describution: 员工服务
company.name: com.com.styz
author.name: liuy
build.artifactId: $project.artifactId$
build.version: $project.version$
修改启动类com.styz.com.styz.microserivcecloud.EmployServiceApplication
添加@EnableEurekaClient注解
@SpringBootApplication
@MapperScan("com.com.styz.microservicecloud.mapper")
@EnableEurekaClient
public class EmployServiceApplication {
public static void main(String[] args) {
SpringApplication.run(EmployServiceApplication.class,args);
}
}
然后可以查看注册中心是否有服务注册进去了。
消费者调用
修改microservicecloud-employconsummer中的com.styz.com.styz.com.styz.microservice.controller.EmployConsumerController
中的
// EMPLOYSERVICE为服务名称
public static final String EMPLOY_PROVIDE_URL="http://EMPLOYSERVICE/employ";
修改pom添加eureka客户端依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
修改启动类添加服务发现注解@EnableDiscoveryClient
@SpringBootApplication
@EnableDiscoveryClient
public class EmployComsumerApplication {
public static void main(String[] args) {
SpringApplication.run(EmployComsumerApplication.class,args);
}
}
修改yml文件
eureka:
client:
service-url:
#单机配置:http://localhost:8211/eureka
defaultZone: http://registry8212:8212/eureka/,http://registry8213:8213/eureka/,http://registry8211:8211/eureka/
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文件
<!-- 添加 ribbon依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
修改启动类
@SpringBootApplication
@EnableDiscoveryClient
//指定某个服务用某种负载均衡算法
@RibbonClient(name = "EMPLOYSERVICE",configuration = MyRules.class)
public class EmployComsumerApplication {
public static void main(String[] args) {
SpringApplication.run(EmployComsumerApplication.class,args);
}
}
com.styz.rules.MyRules
@Configuration
public class MyRules {
@Bean
@Primary
public IRule getRobbinRule(){
return new RandomRule();
}
}
新建自定义负载均衡算法
com.styz.com.styz.com.styz.microservice.robbin.CountRobbinRule
public class CountRobbinRule implements IRule {
private ILoadBalancer loadBalancer;
private AtomicInteger count = new AtomicInteger(0);
private AtomicInteger serverIndex = new AtomicInteger(0);
@Override
public Server choose(Object o) {
List<Server> allServers = loadBalancer.getAllServers();
while (true){
if(count.get() > 5){
if(serverIndex.incrementAndGet() > allServers.size()){
serverIndex.set(serverIndex.get()%allServers.size());
}
count.set(0);
}else {
count.incrementAndGet();
return allServers.get(serverIndex.get());
}
}
}
@Override
public void setLoadBalancer(ILoadBalancer iLoadBalancer) {
loadBalancer = iLoadBalancer;
}
@Override
public ILoadBalancer getLoadBalancer() {
return loadBalancer;
}
}
修改配置文件类com.styz.com.styz.com.styz.microservice.config.ConsummerConfigBean
@Configuration
public class ConsummerConfigBean {
/**
* @LoadBalanced 注解会使用robbin负载均横算法。默认是轮训,如需修改得显示声明对应的算法。
* 如果没有声明,默认就是轮训
* robbin 提供7种轮训算法,我们可以手动扩展实现负载均衡算法。
*/
@Bean
@LoadBalanced
public RestTemplate getRestTemplate(){
RestTemplate restTemplate = new RestTemplate();
return restTemplate;
}
}
启动注册中心,启动服务提供者集群,启动消费者,访问http://localhost:7111/consummer/getById/1 查看负载均衡情况。
引入Feign负载均衡
RestTemplate+robbin是基于微服务名称封装httpclient的方式完成的服务调用。
而Feign是在此基础上又进行了一次封装,使得消费端可以通过注解+接口的方式
用接口的方式完成服务的调用,有点类似于Dubbo中接口调用一样。只是底层实现不一样,
Dubbo是RPC,而Feign是http的Restful调用。
创建microservicecloud-employ-consummer-feign模块
修改pom文件添加Feign支持
<dependencies>
<dependency>
<groupId>com.com.styz.microservicecloud</groupId>
<artifactId>microservicecloud-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</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>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
<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-openfeign</artifactId>
</dependency>
</dependencies>
2.修改microservicecloud-api 添加Feign接口com.styz.microservicecloud.service.EmployClientService
@FeignClient(value = "EMPLOYSERVICE")
public interface EmployClientService {
//注意此时的url是服务端的全路径,不是客户端哦
@RequestMapping(value = "/employ/getAllEmployes",method = RequestMethod.POST)
public List<Employ> getAllEmployes();
@RequestMapping(value = "/employ/getEmployById/{id}",method = RequestMethod.POST)
public Employ getEmployById(@PathVariable("id")long id);
}
修改com.styz.com.styz.com.styz.microservice.controller.EmployConsumerController
@RestController
@RequestMapping("/comsummer")
public class EmployConsumerController {
//EmployClientService 为Feign接口
@Autowired
private EmployClientService clientService;
@RequestMapping("/getById/{id}")
public Employ getEmployById(@PathVariable("id") long id){
return clientService.getEmployById(id);
}
@RequestMapping("/getAllEmployes")
public List<Employ> getAllEmployes(){
return clientService.getAllEmployes();
}
}
修改启动类com.styz.com.styz.com.styz.microservice.EmployComsumerApplication
@SpringBootApplication
@EnableDiscoveryClient
//注意EnableFeignClients 一定要扫描到@FeignClient的包否则会报错
@EnableFeignClients(basePackages = "com.styz.microservicecloud.service")
public class EmployComsumerApplication {
public static void main(String[] args) {
SpringApplication.run(EmployComsumerApplication.class,args);
}
}
此时再次访问http://localhost:7111/consummer/getById/1 查看负载均衡情况
添加熔断Hystrix支持
Hystrix是什么?请自行百度。
新建microservicecloud-employ-consummer-hystrix 模块
修改pom文件
<dependencies>
<dependency>
<groupId>com.com.styz.microservicecloud</groupId>
<artifactId>microservicecloud-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</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>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
<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-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
修改启动类添加
@SpringBootApplication
@EnableDiscoveryClient
//注意EnableFeignClients 一定要扫描到@FeignClient的包否则会报错
@EnableFeignClients(basePackages = "com.styz.microservicecloud.service")
//添加熔断机制
@EnableHystrix
@ComponentScan("com.styz")
public class EmployComsumerApplication {
public static void main(String[] args) {
SpringApplication.run(EmployComsumerApplication.class,args);
}
}
修改controller 添加@HystrixCommand,
一般情况下熔断一般实现在服务提供端,我这里只是demo就实现在消费端了。
@HystrixCommand能捕获异常可以根据异常不同,进行不同的熔断操作。
@RestController
@RequestMapping("/comsummer")
public class EmployConsumerController {
@Autowired
private EmployClientService clientService;
@RequestMapping("/getById/{id}")
@HystrixCommand(fallbackMethod = "processEmployException")
public Employ getEmployById(@PathVariable("id") long id){
Employ employ = clientService.getEmployById(id);
if(null == employ){
throw new RuntimeException("未找到对应ID的员工!");
}
return employ;
}
/**
* 这个方法可以写在服务端,也可以写在消费端,如果异常导致的最好写在服务端,如果非异常,可以实现在消费端
* 方法写在服务端叫熔断,写在消费端叫降级。
* HystrixCommand 注解能实现的熔断,但是缺点非常明显,容易导致方法膨胀:也就是每个方法都需要写一个异常方法
* 方法会非常多,不便与维护。
*
* @param id
* @return
*/
public Employ processEmployException(@PathVariable("id") long id){
Employ employ = new Employ();
employ.setId(id);
employ.setName("未找到对应ID的员工!");
return employ;
}
@RequestMapping("/getAllEmployes")
public List<Employ> getAllEmployes(){
return clientService.getAllEmployes();
}
}
@HystrixCommand 业务代码耦合严重,方法容易膨胀,所以有了Fegin熔断机制
可以在接口上面实现熔断,从而解藕
修改com.styz.microservicecloud.service.EmployClientService
/**
* 服务降级处理:
* 1.添加fallbackFactory 或者Fallback类
* 2.开启服务降级:
* feign:
* hystrix:
* enabled: true
* 注意fallbackFactory类或者Fallback类要能被扫描到。否则不会生效。
*/
@FeignClient(value = "EMPLOYSERVICE",fallbackFactory = EmployClientServiceFallbackFactory.class)
public interface EmployClientService {
//注意此时的url是服务端的全路径,不是客户端哦
@RequestMapping(value = "/employ/getAllEmployes",method = RequestMethod.POST)
public List<Employ> getAllEmployes();
@RequestMapping(value = "/employ/getEmployById/{id}",method = RequestMethod.POST)
public Employ getEmployById(@PathVariable("id")long id);
}
@Component
public class EmployClientServiceFallbackFactory implements InitializingBean,FallbackFactory<EmployClientService> {
@Override
public void afterPropertiesSet() throws Exception {
}
public static class EmployClientServiceFallback implements EmployClientService{
@Override
public List<Employ> getAllEmployes() {
ArrayList<Employ> employs = new ArrayList<>();
employs.add(new Employ().setName("********暂停服务*****"));
System.out.println("*************暂停服务****************");
return employs;
}
@Override
public Employ getEmployById(long id) {
return new Employ(id,"该ID不存在",0L,"");
}
}
@Override
public EmployClientService create(Throwable throwable) {
return new EmployClientServiceFallback();
}
}
开启Fegin降级机制
feign:
hystrix:
enabled: true
此时称之为Feign+fallback 服务降级
何谓服务降级:简单的说就是当整个系统资源不够用时,为了满足某些服务依然可用,就需要忍痛将其他服务停掉,将系统资源释放
用以支持其他服务。此时停掉的服务不能影响整个系统的使用,就需要在消费端在访问不到服务的情况下,将服务进行降级处理。
启动消费者测试一下服务的熔断和降级看看。
添加监控HystrixDashboard支持
创建microservicecloud-employ-consummer-hystrixDashboard模块
修改pom文件
<dependencies>
<dependency>
<groupId>com.com.styz.microservicecloud</groupId>
<artifactId>microservicecloud-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</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>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
<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-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<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-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<resources>
<resource>
<directory>src/main/resource</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<!--添加actor/info信息的描述-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<configuration>
<delimiters>
<delimiter>$</delimiter>
</delimiters>
</configuration>
</plugin>
</plugins>
</build>
修改启动类:
@SpringBootApplication
@EnableDiscoveryClient
//注意EnableFeignClients 一定要扫描到@FeignClient的包否则会报错
@EnableFeignClients(basePackages = "com.styz.microservicecloud.service")
//添加熔断机制
@EnableHystrix
@ComponentScan("com.styz")
//添加服务监控 1.服务端要添加对应的包spring-boot-starter-actuator
@EnableHystrixDashboard
public class EmployComsumerApplication {
public static void main(String[] args) {
SpringApplication.run(EmployComsumerApplication.class,args);
}
}
hystrix.stream
springboot2.0中hystrix.stream url出现404错误问题解决办法1
添加配置类com.styz.com.styz.com.styz.microservice.config.HystrixConfig
@Configuration
public class HystrixConfig {
@Bean
public HystrixMetricsStreamServlet hystrixMetricsStreamServlet(){
return new HystrixMetricsStreamServlet();
}
@Bean
public ServletRegistrationBean registration(HystrixMetricsStreamServlet servlet){
ServletRegistrationBean registrationBean = new ServletRegistrationBean();
registrationBean.setServlet(servlet);
//是否启用该registrationBean
registrationBean.setEnabled(true);
registrationBean.addUrlMappings("/hystrix.stream");
return registrationBean;
}
}
修改yml文件
#需要暴露的url:
#这里暴露了/actuator/hystrix.stream,/actuator/info
management:
endpoints:
web:
exposure:
include:
- hystrix.stream
- info
# 添加服务Info信息
info:
app.name: ${eureka.instance.instance-id}
app.describution: 带熔断监控器的消费者
company.name: com.com.styz
author.name: liuy
build.artifactId: $project.artifactId$
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文件
<!--添加Turbine依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-turbine</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix-turbine</artifactId>
</dependency>
修改启动类添加@EnableTurbine注解
@SpringBootApplication
@EnableDiscoveryClient
//注意EnableFeignClients 一定要扫描到@FeignClient的包否则会报错
@EnableFeignClients(basePackages = "com.styz.microservicecloud.service")
//添加熔断机制
@EnableHystrix
@ComponentScan("com.styz")
//添加服务监控 1.服务端要添加对应的包spring-boot-starter-actuator
@EnableHystrixDashboard
@EnableTurbine
public class EmployConsummerTurbineApplication {
public static void main(String[] args) {
SpringApplication.run(EmployConsummerTurbineApplication.class,args);
}
}
添加turbine配置
turbine:
# app-config表示待监测的服务名称
app-config: EmployComsummer-HystrixDashboard,EmployComsummer-HystrixDashboard-Turbine
aggregator:
cluster-config: default
cluster-name-expression: new String("default")
turbine.appConfig :配置Eureka中的serviceId列表,表明监控哪些服务
turbine.aggregator.clusterConfig :指定聚合哪些集群,多个使用","分割,默认为default。可使用http://.../turbine.stream?cluster={clusterConfig之一}访问
turbine.clusterNameExpression :
- clusterNameExpression指定集群名称,默认表达式appName;此时:turbine.aggregator.clusterConfig需要配置想要监控的应用名称;
- 当clusterNameExpression: default时,turbine.aggregator.clusterConfig可以不写,因为默认就是default;
- 当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文件
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-actuator</artifactId>
</dependency>
</dependencies>
配置:
eureka:
client:
service-url:
#单机配置:http://localhost:8211/eureka
defaultZone: http://registry8212:8212/eureka/,http://registry8213:8213/eureka/,http://registry8211:8211/eureka/
register-with-eureka: true
fetch-registry: true
instance:
instance-id: GateWay
prefer-ip-address: true
zuul:
ignoredServices: '*'
host:
connect-timeout-millis: 20000
socket-timeout-millis: 20000
routes:
employservice:
path: /employ/**
serviceId: employservice
stripPrefix: false
sensitiveHeaders:
employcomsummer-hystrix:
path: /consummer/**
serviceId: employcomsummer-hystrix
stripPrefix: false
sensitiveHeaders:
employcomsummer-hystrixdashboard:
path: /dashboard/**
serviceId: employcomsummer-hystrixdashboard
stripPrefix: false
sensitiveHeaders:
baidu:
path: /baidu/**
url: http://www.baidu.com/
启动类添加
@SpringBootApplication
@EnableZuulProxy
@EnableDiscoveryClient
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class,args);
}
}
添加配置服务Config支持
新建microservicecloud-config模块
修改pom文件
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
创建com.styz.microservicecloud.ConfigServerApplication
@SpringBootApplication
@EnableConfigServer
public class ConfigServerApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigServerApplication.class,args);
}
}
修改配置文件
spring:
cloud:
config:
server:
native:
search-locations: classpath:/config
# 本地模式
profiles:
active: native
server:
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 其实原来就有。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
3.修改bootstrap.yml 添加如下内容
spring:
application:
name: EmployService
cloud:
config:
uri: http://config:8888
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文件
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-actuator</artifactId>
</dependency>
</dependencies>
2.新建类com.styz.microservicecloud.GItConfigServerApplication
@EnableConfigServer
public class GItConfigServerApplication {
public static void main(String[] args) {
SpringApplication.run(GItConfigServerApplication.class,args);
}
}
3.修改yml
spring:
application:
name: GitConfigServer
cloud:
config:
# label 表示是哪个分支
label: master
server:
git:
# git用户密码私有仓库必填
username:
password:
# uri 是git的地址
uri: https://github.com/liuyong520/microservicecloud
# search-paths 搜索git仓库哪个目录,相对地址
search-paths: microservicecloud-config-dir
eureka:
client:
register-with-eureka: true
service-url:
defaultZone: http://registry8212:8212/eureka/,http://registry8213:8213/eureka/,http://registry8211:8211/eureka/
instance:
instance-id: GitConfigServer
prefer-ip-address: true
server:
port: 8888
server端就此改造完了
测试一下
访问http://localhost:8888/config/dev 就能访问到application-dev.yml配置。
访问http://localhost:8888/employservice/default 就能访问到employsevice配置。
修改microservicecloud-employ-provider-8911
采用服务发现的方式连接configsever。
spring:
application:
name: EmployService
cloud:
config:
name: EmployService #指定配置文件名称
profile: default
label: master
discovery:
enabled: true
service-id: GitConfigServer #configserver服务
重启服务端看看是否正常启动。
添加链路跟踪
何谓链路跟踪?
在分布式系统中往往一次简单的请求,往往涉及到一系列的服务调用,服务A调用服务B,服务B调用服务C。这样
的服务链上如果某个服务发生故障,无法快速定外到故障点,从而无法快速定位问题。而链路
跟踪是就是跟踪整个服务之间的调用链,监控每个服务间的调用情况,以备在调用出现问题时,能快速定位问题。
zipKin 简介
Zipkin是一种分布式跟踪系统。它有助于收集解决服务体系结构中的延迟问题所需的计时数据。功能包括收集和查找此数据。
如果日志文件中有跟踪ID,则可以直接跳转到该文件。否则,您可以根据服务,操作名称,标签和持续时间等属性进行查询。将为您总结一些有趣的数据,例如在服务中花费的时间百分比,以及操作是否失败
Zipkin UI还提供了一个依赖关系图,显示了每个应用程序通过的跟踪请求数。这有助于识别聚合行为,包括错误路径或对已弃用服务的调用。
zipKin环境搭建
1.docker环境下:
docker run --name zipkin -d -p 9411:9411 openzipkin/zipkin
2.物理机
curl -sSL https://zipkin.io/quickstart.sh | bash -s
java -jar zipkin.jar
访问http://localhost:9411/ 出现zipkin UI界面
为了 演示一下链路跟踪需要搭建一个调用链环境,我这里用一个消费端和服务端来演示
修改服务提供者
1.新建microservicecloud-employ-provider-8911-sleuth
改造一下microservicecloud-employ-provider-8911
修改pom
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
修改yml文件
spring:
application:
name: EmployService
#添加链路跟踪
sleuth:
web:
client:
enabled: true
sampler:
probability: 1.0
zipkin:
base-url: http://k8s-n3:9411/
至此服务端改造完成
修改消费者
1.新建microservicecloud-employ-consummer-hystrix-sleuth模块
改造一下microservicecloud-employ-consummer-hystrix
修改pom文件
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
然后修改一下yml文件
server:
port: 7115
spring:
application:
name: EmployComsummer-Hystrix
devtools:
restart:
enabled: true
sleuth:
web:
client:
enabled: true
sampler:
probability: 1.0 #采样比例 1表示100%全部采样
zipkin:
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
无管理界面:
docker run --localhost rabbit-host --name my_rabbit -d -p 5672:5672 rabbitmq
有管理界面:
docker run --localhost rabbit-host --name my_rabbit -d -p 5672:5672 -p 15672:15672 rabbitmq:management
账号:guest 密码:guest
调整之前的消费者和服务者
修改pom文件
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-stream-rabbit</artifactId>
</dependency>
修改yml文件
spring
sleuth:
web:
client:
enabled: true
sampler:
probability: 1.0
zipkin:
sender:
type: rabbit
rabbitmq:
password: guest
username: guest
host: k8s-n3
port: 5672
virtual-host: /
修改zipkin服务端
docker run -d -p9411:9411 -e "RABBIT_ADDRESSES=rabbithost:5672" openzipkin/zipkin
如果你的rabbitMq用户名密码不是guest需要指定环境变量。
结果展示
详细源码参见GitHub 地址:https://github.com/liuyong520/microservicecloud
跟着我一步一步的搭建一个基于springcloud的微服务实例的更多相关文章
- 利用SpringCloud搭建一个最简单的微服务框架
http://blog.csdn.net/caicongyang/article/details/52974406 1.微服务 微服务主要包含服务注册,服务发现,服务路由,服务配置,服务熔断,服务降级 ...
- 基于SpringCloud的微服务架构实战案例项目,以一个简单的购物流程为示例
QuickStart 基于SpringCloud体系实现,简单购物流程实现,满足基本功能:注册.登录.商品列表展示.商品详情展示.订单创建.详情查看.订单支付.库存更新等等. 每个业务服务采用独立的M ...
- 一个不错的架构图:基于SpringCloud的微服务项目
https://github.com/hanlin5566/HJ-MicroService
- 通过Dapr实现一个简单的基于.net的微服务电商系统(四)——一步一步教你如何撸Dapr之订阅发布
之前的章节我们介绍了如何通过dapr发起一个服务调用,相信看过前几章的小伙伴已经对dapr有一个基本的了解了,今天我们来聊一聊dapr的另外一个功能--订阅发布 目录:一.通过Dapr实现一个简单的基 ...
- 通过Dapr实现一个简单的基于.net的微服务电商系统(十一)——一步一步教你如何撸Dapr之自动扩/缩容
上一篇我们讲到了dapr提供的bindings,通过绑定可以让我们的程序轻装上阵,在极端情况下几乎不需要集成任何sdk,仅需要通过httpclient+text.json即可完成对外部组件的调用,这样 ...
- 通过Dapr实现一个简单的基于.net的微服务电商系统(三)——一步一步教你如何撸Dapr
目录:一.通过Dapr实现一个简单的基于.net的微服务电商系统 二.通过Dapr实现一个简单的基于.net的微服务电商系统(二)--通讯框架讲解 三.通过Dapr实现一个简单的基于.net的微服务电 ...
- 通过Dapr实现一个简单的基于.net的微服务电商系统(五)——一步一步教你如何撸Dapr之状态管理
状态管理和上一章的订阅发布都算是Dapr相较于其他服务网格框架来讲提供的比较特异性的内容,今天我们来讲讲状态管理. 目录:一.通过Dapr实现一个简单的基于.net的微服务电商系统 二.通过Dapr实 ...
- 通过Dapr实现一个简单的基于.net的微服务电商系统(六)——一步一步教你如何撸Dapr之Actor服务
我个人认为Actor应该是Dapr里比较重头的部分也是Dapr一直在讲的所谓"stateful applications"真正具体的一个实现(个人认为),上一章讲到有状态服务可能很 ...
- 通过Dapr实现一个简单的基于.net的微服务电商系统(七)——一步一步教你如何撸Dapr之服务限流
在一般的互联网应用中限流是一个比较常见的场景,也有很多常见的方式可以实现对应用的限流比如通过令牌桶通过滑动窗口等等方式都可以实现,也可以在整个请求流程中进行限流比如客户端限流就是在客户端通过随机数直接 ...
随机推荐
- EasyNetQ使用(二)【连接RabbitMQ,SSL连接,Logging】
如果你连接过关系数据库,例如SQL Server.你会发现EasyNetQ处理connections有点奇怪.和关系数据库通讯一直都是通过client开始的.Client 打开一个连接, 发出一个SQ ...
- centos(linux)--vsftpd配置
1.安装 执行 yum -y install vsftpd 注:(1)是否使用sudo权限根据个人的具体情况 (2)rpm -qa | grep vsftpd 可以通过这个检查是否已经安装vsftpd ...
- 欢迎访问我的csdn博客
csdn博客:https://blog.csdn.net/qq_27307175 这个里面有:许许多多的专业文章. 本人主要研究:网络工程,VMware虚拟化,docker容器,以及Linux等技术, ...
- 虚拟机中CentOS 7 x64图形化界面的安装
VMware的初始设置如下: 图1 待虚拟机读取完iso,出现此界面 图2 我们主要是安装图形化界面的系统,所以在软件选择栏下如图选择: 图3 设置root密码,创建用户,等候安装完成: 图4 安装完 ...
- appium(屏幕滑动)
class handleswipe(): """ 屏幕滑动操作 """ def __init__(self, driver, functio ...
- Spring 控制器重定向
1.示例 return "redirect:/allUser"; redirect是跳转的意思后面是跳转的页面
- Python 解leetcode:728. Self Dividing Numbers
思路:循环最小值到最大值,对于每一个值,判断每一位是否能被该值整除即可,思路比较简单. class Solution(object): def selfDividingNumbers(self, le ...
- 聊聊BIO、NIO与AIO的区别
题目:说一下BIO/AIO/NIO 有什么区别?及异步模式的用途和意义? 1F 说一说I/O首先来说一下什么是I/O? 在计算机系统中I/O就是输入(Input)和输出(Output)的意思,针对不同 ...
- Educational Codeforces Round 74 (Rated for Div. 2)补题
慢慢来. 题目册 题目 A B C D E F G 状态 √ √ √ √ × ∅ ∅ //√,×,∅ 想法 A. Prime Subtraction res tp A 题意:给定\(x,y(x> ...
- 剑指offer17:输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)
1 题目描述 输入两棵二叉树A,B,判断B是不是A的子结构.(ps:我们约定空树不是任意一个树的子结构) 2 思路和方法 (1)先在A中找和B的根节点相同的结点 (2)找到之后遍历对应位置的其他结点, ...