springcloud 学习项目
springcloud 学习项目
- 概述
- 1.springcloud是什么,为什么要学springcloud,不学springcloud又怎样呢。
- 一、创建一个简单的springcloud项目
- 1_1、创建数据库和一个maven项目
- 1_1_1 创建数据库db01,并创建表格dept,数据如下
- 1_1_2 创建maven项目并删掉src文件夹,然后添加依赖
- 1_2、创建springcloud-api模块
- 1_2_1.导入依赖
- 1_2_2 创建实体类pojo
- 1_3 创建一个微服务提供者(springcloud-provider-dept-8001):
- 1_3_1导入依赖
- 1_3_2 配置application.yml
- 1_3_3 配置dao层,service层,controller层
- 1_3_3_1 dao/DeptDao:实体类的的增删改查方法的实现
- 1_3_3_2 service层
- 1_3_3_4 controller层
- 1_3_4配置开启springboot服务器的类
- 1_3_5对controller进行测试
- 1_4创建服务消费者springcloud-consumer-dept-80
- 1_4_1 导入依赖
- 1_4_2 在applicaction.yml中修改端口号
- 1_4_3 将RestTemplate注册到bean中
- 1_4_4 配置controller层(通过restTemplate调用服务器的url)
- 1_4_5 配置开启springboot服务器的类的类名
- 1_4_5测试
- 1_5创建eureka服务器(springcloud-eureka-7001)(已过时)
- 1_5_1导入依赖
- 1_5_2application.yml配置
- 1_5_3 配置springboot启动类
- 1_5_4 测试
- 1_5_5 将8001和80配置为eureka服务器的的Client
- 1_5_5_1在原有依赖上加上eureka依赖
- 1_5_5_2修改application.yml
- 1_5_5_3该启动类添加@EnableEurekaClient注解
- 1_5_5_4测试
- 1_6 通过actuator完善eureka的监控信息
- 1_6_1 导入actuator依赖
- 1_6_2 在eureka界面查看客户详细信息:在application.yml中配置info
- 1_6_2通过controller(即http请求)查看客户详细信息:使用discovery
- 1_6_2_1配置访问信息的controller控制器
- 1_6_2_2在启动类中添加@EnableDiscoveryClient注解
- 1_6_2_3进入[http://localhost:8001/dept/discovery](http://localhost:8001/dept/discovery)查看效果
- 1_7搭建eureka集群环境
- 1_7_1复制eureka7001,生成7002,7003
- 1_7_2修改各个eureka服务器的主机名hostname,使得主机名唯一
- 1_7_3模拟多台独立服务器(域名)组成集群的效果:修改hosts中的域名映射关系
- 1_7_4 测试:使用服务器提供者8001来进行测试
- 1_7_5将服务提供者向所以eureka服务器连通
- 1_7_5配置服务端集群
- (1)复制数据库生成完全一样的db02和db03,并修改datasource属性为当前数据库。
- (2)创建多台服务提供者:复制springcloud-provider-dept-8001模块生成8002和8003
- 1_8在客户端实现负载均衡
- 1_8_1 使用ribbon自带负载均衡算法:@LoadBalanced
- 1_8_2 使用ribbon实现自定义负载均衡算法
- (1)自己编写一个Rule类继承AbstractLoadBalancerRule,并添加choose(ILoadBalancer lb, Object key) 方法。
- (2)将该策略添加到项目中(在启动类上使用@RibbonClient)
- (3)测试
- 1_8_3 使用nginx实现负载均衡思路图
- 1_8_4 使用openFeign实现负载均衡
- 1_9 使用feign替代RestTemplate(其内部集成了RestTemplate)
- 1_9_1 复制然后创建一个新的服务消费者model用来测试feign
- 1_9_2 在原来依赖的基础上添加feign依赖
- 1_9_3 修改启动类名为FeignDeptConsumer_80,并添加注解@EnableFeignClients扫描FeignClient
- 1_9_4在Fiegn所在的服务消费者中添加service层(使用@FeignClient)
- 1_9_5在controller不使用RestTemplate,而是使用DeptClientService来调用服务提供者。
- 1_9_6测试
- 1_10分布式系统的延迟和容错处理方式
- Hytrix实现服务熔断(已过时)
- 1_10_1复制springcloud-provider-dept-8001生成一个新的服务提供者:springcloud-provider-dept-hystrix-8001
- 1_10_2添加Hystrix依赖到原有依赖中
- 1_10_3在application.yml中修改instance-id,方便区分
- 1_10_4修改启动类名为:DeptProviderHystrix_8001.java,并添加@EnableCircuitBreaker
- 1_10_5修改controller层(添加处理错误的功能)
- 1_10_6测试`http://localhost/consumer/dept/get/6`
- feign实现服务降级
- 1_10_7在feign实现负载均衡的基础上添加一个类
- 1_10_8给servicec层的接口添加服务降级画面显示(fallbackFactory)
- 1_10_9测试
- 熔断监控DashBoard监控请求(流量)
- 1_10_10新建一个模块:`springcloud-consumer-hystrix-dashboard`,并往dashboard模块中添加依赖
- 1_10_11设置dashboard模块的端口
- 1_10_12配置启动类
- 1_10_13在`springcloud-provider-dept-hystrix-8001`的启动类上添加servlet
- 1_10_14测试
- 1_11路由网关Zuul(已过时)
- 1_11_1添加依赖
- 1_11_2 配置application.yml
- 1_11_3修改域名映射关系:C:\Windows\System32\drivers\etc\hosts
- 1_11_4配置启动类ZuulApplication_9527
- 1_11_5测试
- 1_11_5实现域名伪装:修改9527一下application.yml的zuul配置,并测试
- 1_12config
- Git环境配置
- 1_12_1配置Git项目环境
- 1_12_2在git码云上创建一个项目,并获取到本地。然后新建一个application.yml文档,并添加上以下内容。
- 1_12_3上传到git远程服务器。
- 配置config服务端并连接git的远程仓库
- 1_12_4导入依赖
- 1_12_5配置application.yml
- 1_12_6 配置启动类
- 1_12_7测试是否联通
- 通过git进行远程资源 配置 本地项目。
- 1_12_8在git项目目录下添加一个yml文档。
- 1_12_9 push到远程服务器
- 1_12_10 创建springcloud-config-client-3355模块,并配置依赖
- 1_12_11 配置配置文件
- 1_12_12启动类和controller层
- 1_12_12访问`http://localhost:8201/config`测试
- 远程配置资源项目(这里以7001服务器为例)
- 1_12_13 配置并上传远程资源
- 1_12_14 创建一个7001模块,并导入依赖
- 1_12_15创建bootstrap.yml和application.yml(核心)
- 1_12_16 配置启动类
- 1_12_17测试
- -----------------------springcloud新技术-----------------------
- 一、Nacos:服务中心+配置中心
- 1、Nacos作为服务中心
- 1.1 下载、启动nacos
- 1.2 nacos替代eureka作为服务注册中心
- (1) 在nacos客户端(如服务提供者、服务消费者)上添加依赖
- (2) 对eureka客户端进行配置
- (3)配置启动类
- (4)在nacos中发现该客户端成功
- 2.1.3 nacos替代Config作为服务配置中心
- 2.1.4 nacos集群和持久化配置
- 2、Nacos作为配置中心
- GateWay网关
- 2.1 GateWay+Eureka
- 2.1.1 GateWay实现路由效果
- (1) 添加依赖
- (2)添加配置文件
- (3)配置启动类
- (4)测试:实现路由功能
- 2.1.2 Gateway配置动态路由,实现负载均衡
- (1)在2.1.1基础上更改配置文件
- (2) 测试负载均衡效果
- 2.1.2 Gateway如何自定义负载均衡策略呢
- 2.1.3 Gateway的Predicate
- 2.1.4 GateWay的filter
- Gateway自带的filter
- 使用自定义filter(全局GlobalFilter)
- 2.2 Nacos+Eureka
- 2.2.1
- 【附加】springcloud原理和思想
- CAP理论
- ribbon:客户端负载均衡的工具
概述
1.springcloud是什么,为什么要学springcloud,不学springcloud又怎样呢。
一、创建一个简单的springcloud项目
本程序的结构图如下
1_1、创建数据库和一个maven项目
1_1_1 创建数据库db01,并创建表格dept,数据如下
1_1_2 创建maven项目并删掉src文件夹,然后添加依赖
点击查看dependencyManagement和dependencys的区别
1、关于打包方式:
pom:(父模块)用在父级工程或聚合工程中,用来做jar包的版本控制,必须指明这个聚合工程的打包方式为pom
war:(子模块)将会打包成war,发布在服务器上,如网站或服务。用户可以通过浏览器直接访问,或者是通过发布服务被别的工程调用
2、这里使用了propertieyManagement
来管理依赖的版本:
dependencies
即使在子项目中不写该依赖项,那么子项目仍然会从父项目中继承该依赖项(全部继承)
dependencyManagement
里只是声明依赖,并不实现引入,因此子项目需要显示的声明需要用的依赖。实际上只要在最大的项目内使用dependencyManagement之后(可以不在子模块中写同样的代码重复控制版本),那么子子模块、子子子模块都会默认使用dependencyManagement规定的版本。
<properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><maven.compiler.source>1.8</maven.compiler.source><maven.compiler.targer>1.8</maven.compiler.targer><junit.version>4.12</junit.version><lombok.version>1.16.18</lombok.version><log4j.version>1.2.17</log4j.version></properties>
<!-- 1.:packaging使用pom的打包方式--><packaging>pom</packaging>
<!-- **************2.依赖管理:仅管理依赖,但不导入依赖***********--><dependencyManagement><dependencies>
<!-- springcloud的依赖(与其他依赖相比是pom类型)--><!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-dependencies --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>Greenwich.SR1</version><type>pom</type><scope>import</scope></dependency>
<!-- springBoot依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>2.1.4.RELEASE</version><type>pom</type><scope>import</scope></dependency>
<!-- 连接数据库和设计院--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.47</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.10</version></dependency>
<!-- springBoot 启动器(内涵Mybatis)--><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>1.3.2</version></dependency>
<!-- **********以下是与日志测试相关的********--><dependency><groupId>ch.qos.logback</groupId><artifactId>logback-core</artifactId><version>1.2.3</version></dependency>
<!-- junit--><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>${junit.version}</version><scope>test</scope></dependency>
<!-- lombok--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>${lombok.version}</version></dependency>
<!-- log4j--><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>${log4j.version}</version></dependency></dependencies></dependencyManagement><!--配置打包插件build--><!-- <build>--><!-- <resources></resources> --><!-- </build>-->
1_2、创建springcloud-api模块
1_2_1.导入依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>springCloud_01</artifactId><groupId>org.example</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>springcloud-api</artifactId><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target></properties>
<!-- 当前module中自己需要的依赖,如果父依赖中已经配制了版本,这里就不用写了--><dependencies><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency></dependencies>
</project>
1_2_2 创建实体类pojo
@Data
@NoArgsConstructor
//使用链式写法(该类中的所有setter和getter方法的返回值都是this哦)
//@Accessors(prefix = "xxx")是忽略以xxx开头的属性,其余属性使用链式写法
@Accessors(chain = true)
public class Dept implements Serializable {//Dept实体列,orm对象关系映射private Long deptno;//主键private String dname;//这个数据是存在哪个数据库的字段~微服务,一个服务对应一个数据库,同一个信息可能存在不同的数据库private String db_source;public Dept(String name){this.dname=dname;}
}
1_3 创建一个微服务提供者(springcloud-provider-dept-8001):
1_3_1导入依赖
热部署工具非常好用,是指我们在程序中修改java代码之后能够生效。
使用方法很简单:1、添加依赖 2、修改服务器设置
参考文章
<dependencies>
<!-- 1、添加Pojo实体类--><dependency><groupId>org.junjun</groupId><artifactId>springcloud-api</artifactId><version>1.0-SNAPSHOT</version></dependency><!-- 2、springboot和测试类--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>com.junjun.test</scope></dependency><dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter-api</artifactId><scope>com.junjun.test</scope></dependency><!-- 3、数据库相关--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId></dependency><!-- 4、热部署工具:就是我们改动java代码后不用手动重启项目--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId></dependency></dependencies>
1_3_2 配置application.yml
server:port: 8001
# mybatis的配置
mybatis:type-aliases-package: com.junjun.springcloud.pojomapper-locations: classpath:mybatis/mapper/*.xmlconfig-location: classpath:mybatis/mybatis-config.xml#spring服务器和数据库的配置
spring:application:name: springcloud-provider-deptdatasource:type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: org.gjt.mm.mysql.Driverurl: jdbc:mysql://localhost:3306/db01?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezeno=GMT%2B8username: rootpassword: 3333
1_3_3 配置dao层,service层,controller层
1_3_3_1 dao/DeptDao:实体类的的增删改查方法的实现
使用@Mapper就能被对应的xml文档用namespace=""给找到(而且有提示)。
@Mapper
@Repository
public interface DeptDao {public boolean addDept(Dept dept);public Dept queryById(Long id);public List<Dept> queryAll();
}
—DeptDao在sources中的对应的mapper.xml
虽然会爆红报错(xml中找不到Dept),但是可以正常运行
<?xml version="1.0" encoding="UTF8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--命名空间是对应的接口--><mapper namespace="com.junjun.springcloud.dao.DeptDao"><insert id="addDept" parameterType="Dept">insert into dept(dname,db_source)value (#{dname},DATABASE())</insert>
<!-- 只有一个参数,因此#{}中可以随便写--><select id="queryById" resultType="Dept" parameterType="Long">select * from dept where deptno=#{deptno};</select><select id="queryAll" resultType="Dept">select * from dept;</select>
</mapper>
1_3_3_2 service层
--------service/DeptService
public interface DeptService {public boolean addDept(Dept dept);public Dept queryById(Long id);public List<Dept> queryAll();
}
--------service/DeptServiceImpl
@Service
public class DeptServiceImpl implements DeptService{@Autowiredprivate DeptDao deptDao;@Overridepublic boolean addDept(Dept dept) {return deptDao.addDept(dept);}@Overridepublic Dept queryById(Long id) {return deptDao.queryById(id);}@Overridepublic List<Dept> queryAll() {return deptDao.queryAll() ;}
}
1_3_3_4 controller层
-------controller/DeptController
//提供Restful服务!
@RestController
public class DeptController {@Autowiredprivate DeptService deptService;@PostMapping("/dept/add")public boolean addDept(Dept dept){return deptService.addDept(dept);}
// 带占位符的url是springMVC的重要功能,请求中的{xxx}将会被传送到@PathVariable("xxx")中去@GetMapping("/dept/get/{id}")public Dept getDept(@PathVariable("id") Long id){return deptService.queryById(id);}@GetMapping("/dept/list")public List<Dept> getAll(){return deptService.queryAll();}
}
1_3_4配置开启springboot服务器的类
@SpringBootApplication
public class DeptProvider_8001 {public static void main(String[] args) {SpringApplication.run(DeptProvider_8001.class,args);}
}
1_3_5对controller进行测试
1_4创建服务消费者springcloud-consumer-dept-80
1_4_1 导入依赖
<dependencies><!-- 1、添加Pojo实体类--><dependency><groupId>org.junjun</groupId><artifactId>springcloud-api</artifactId><version>1.0-SNAPSHOT</version></dependency><!-- 2、springboot--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency></dependencies>
1_4_2 在applicaction.yml中修改端口号
server:port: 80
1_4_3 将RestTemplate注册到bean中
相当于在xml中用< bean/>注册,这种方式常用于框架中已经存在的类,自己定义的类通常会使用@Component在定义时就一步注册
@Configuration
public class ConfigBean {@Beanpublic RestTemplate getRestTemplate(){return new RestTemplate();}
}
1_4_4 配置controller层(通过restTemplate调用服务器的url)
1.消费者不应该有service层,而是调用服务提供者的service层,我们可以通过RestTemplate来申请调用服务提供者的url。
2.RestTemplate是Spring提供的一个访问Http服务的客户端类。服务消费者通过restTamplate给服务提供者发送HTTP请求并接受响应。。简单来说就是restTamplate可以用来调用请求并得到该服务器运行后的返回结果。
@RestController
public class DeptConsumerController {@Autowireprivate RestTemplate restTemplate;private static final String REST_URL_PREFIX="http://localhost:8001";//getForObject的三个参数是:url,返回值类型,占位符传参@RequestMapping("/consumer/dept/add")public boolean add(@RequestBody Dept dept){return restTemplate.postForObject(REST_URL_PREFIX+"/dept/add",dept,Boolean.class);}//实现消费者和访问者完全解耦(用户访问需要经过一次转发)@RequestMapping("/consumer/dept/get/{id}")public Dept get(@PathVariable("id") Long id){return restTemplate.getForObject(REST_URL_PREFIX+"/dept/get/"+id,Dept.class);}@RequestMapping("/consumer/dept/list")public List<Dept> list(){return restTemplate.getForObject(REST_URL_PREFIX+"/dept/list", List.class);}
}
1_4_5 配置开启springboot服务器的类的类名
@SpringBootApplication
public class DeptConsumer_80 {public static void main(String[] args) {SpringApplication.run(DeptConsumer_80.class);}
}
1_4_5测试
1_5创建eureka服务器(springcloud-eureka-7001)(已过时)
eureka会提供服务注册和发现
1_5_1导入依赖
只需要eureka服务器,这样就能开启服务器了。当然,eureka-server只是具有服务器最基本的功能(@SpringBootApplication),但是却没有springboot的各种注解,如@Component,@Autowired等。
<dependencies>
<!-- eureka服务端--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-eureka-server</artifactId><version>1.4.6.RELEASE</version></dependency></dependencies>
1_5_2application.yml配置
- eureka: client: register-with-eureka
表示是否想eureka注册中心注册自己,默认是true。
1,如果true表示要注册的话得在defaultZone提供一个注册中心地址,说明在这个注册中心注册
2.如果false表示不注册。一般eureka服务器不会在注册中心注册,只有服务提供者和消费者才要注册。- eureka: client: fetch-registry
表示是否从Eureka Server获取注册中心的服务信息,默认值是true
1.eureka服务器没有必要获取注册中心的注册信息,所以用false
2.eureka客户才需要获取注册信息来决定给哪一个服务器发送信息eureka: client: service-url: defaultZone:
的作用?????:
service-url: defaultZone:是默认服务注册中心地址,默认是http://localhost:端口/eureka ;多个地址可使用 , 分隔。在eureka服务器和客户开启时都向这个地址进行注册,实际上,eureka服务器集群原理就是注册中心相互注册,但是不开启检索服务的能力(fetch-registry: false)。
如果服务器或客户开启了register-with-eureka但是填写的defaultZone是无效地址 >就会报错Eureka was unable to refresh its cache! status = Cannot execute request on any known server
如果服务器不开启register-with-eureka但是填写的defaultZone是非http:地址(不合语法)>就会无法显示查询注册者的信息。如下
server:port: 7001
eureka:instance:hostname: localhost #Eureka服务端的实例名称client:register-with-eureka: false # 表示是否想eureka注册中心注册自己,默认值都是truefetch-registry: false #表示是否从Eureka Server获取注册中心的服务信息,eureka服务端没有必要获取注册中心的注册信息,默认值都是trueservice-url:defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/# http://${eureka.instance.hostname}:${server.port}/eureka/就是http://localhost:7001/eureka/,使用了赋值操作,实际上$(eureka.instance.hostname)就是localhost,${server.port}就是7001,这都在上面定义过了。
1_5_3 配置springboot启动类
@SpringBootApplication
@EnableEurekaServer//EnableEurekaServer是开启服务器的启动类,他能够接受别人注册进来~
public class EurekaServer_7001 {public static void main(String[] args) {SpringApplication.run(EurekaServer_7001.class);}
}
1_5_4 测试
即使能显示出如下界面也不代表没有配置错误,application.yml仍然有可能错误通过http://localhost:7001/来访问测试Eureka服务器是否搭建是否成功。
1_5_5 将8001和80配置为eureka服务器的的Client
1_5_5_1在原有依赖上加上eureka依赖
spring-cloud-starter-eureka已经可以作为服务器开启了,但是没有springboot的核心功能。
<dependencies>
<!-- 1、添加Pojo实体类--><dependency><groupId>org.junjun</groupId><artifactId>springcloud-api</artifactId><version>1.0-SNAPSHOT</version></dependency><!-- 2、springboot,都可以不用了,可以用eureka启动服务器--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- 3、数据库相关--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId></dependency><!-- 4、热部署工具:就是我们改动java代码后不用手动重启项目--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId></dependency><!-- 5、eureka客户端--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-eureka</artifactId><version>1.4.6.RELEASE</version></dependency></dependencies>
1_5_5_2修改application.yml
server:port: 8001
# mybatis的配置
mybatis:type-aliases-package: com.junjun.springcloud.pojomapper-locations: classpath:mybatis/mapper/*.xmlconfig-location: classpath:mybatis/mybatis-config.xml#spring的配置
spring:application:name: springcloud-provider-deptdatasource:type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: org.gjt.mm.mysql.Driverurl: jdbc:mysql://localhost:3306/mydb?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezeno=GMT%2B8username: rootpassword: 3333#Eureka的配置
eureka:client:service-url:defaultZone: http://localhost:7001/eureka/
1_5_5_3该启动类添加@EnableEurekaClient注解
@SpringBootApplication
@EnableEurekaClient//在程序启动之后会自动注册到Eureka服务端中!通过http://localhost:7001/能进入Eureka界面能看见注册的Eureka
public class DeptProvider_8001 {public static void main(String[] args) {SpringApplication.run(DeptProvider_8001.class,args);}
}
1_5_5_4测试
先启动7001,进入http://localhost:7001/,再启动8001,然后刷新http://localhost:7001/
1.若没有出现也由是springcloud-eureka-7001的application.yml出现了问题。
1_6 通过actuator完善eureka的监控信息
1_6_1 导入actuator依赖
<dependencies>
<!-- 1、添加Pojo实体类--><dependency><groupId>org.junjun</groupId><artifactId>springcloud-api</artifactId><version>1.0-SNAPSHOT</version></dependency><!-- 2、springboot,都可以不用了,可以用eureka启动服务器--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- 3、数据库相关--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId></dependency><!-- 4、热部署工具:就是我们改动java代码后不用手动重启项目--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId></dependency><!-- 5、eureka客户端--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-eureka</artifactId><version>1.4.6.RELEASE</version></dependency>
<!-- 6、actuator完善监控信息--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency></dependencies>
1_6_2 在eureka界面查看客户详细信息:在application.yml中配置info
server:port: 8001
# mybatis的配置
mybatis:type-aliases-package: com.junjun.springcloud.pojomapper-locations: classpath:mybatis/mapper/*.xmlconfig-location: classpath:mybatis/mybatis-config.xml
#spring的配置
spring:application:name: springcloud-provider-dept #本应用在Eureka中的Application名称datasource:type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: org.gjt.mm.mysql.Driverurl: jdbc:mysql://localhost:3306/mydb?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezeno=GMT%2B8username: rootpassword: 3333
#Eureka的配置
eureka:client:service-url:defaultZone: http://localhost:7001/eureka/instance:instance-id: springcloud-provider-dept8001 #修改eureka中的默认描述信息
#info配置:点击Status:UP就会得到eureka客户详细信息:{"app":{"name":"junjun-springcloud"},"company":{"name":"blog.junjun.com"}}
info:app.name: junjun-springcloudcompany.name: blog.junjun.com
再先后开启7001和8001,然后进入http://localhost:7001/网页。
1_6_2通过controller(即http请求)查看客户详细信息:使用discovery
1_6_2_1配置访问信息的controller控制器
@RestController
public class DeptController {@Autowiredprivate DeptService deptService;@Autowired//用来获取一些配置的信息,得到具体的微服务private DiscoveryClient client;//import org.springframework.cloud.client.discovery.DiscoveryClient;@PostMapping("/dept/add")public boolean addDept(Dept dept){return deptService.addDept(dept);}
// 带占位符的url是springMVC的重要功能,请求中的{xxx}将会被传送到@PathVariable("xxx")中去@GetMapping("/dept/get/{id}")public Dept getDept(@PathVariable("id") Long id){return deptService.queryById(id);}@GetMapping("/dept/list")public List<Dept> getAll(){return deptService.queryAll();}//注册进来的微服务~获取一些消息@GetMapping("/dept/discovery")public Object discovery(){//获取微服务列表的清单List<String> services = client.getServices();System.out.println("discovery=>services"+services);//通过eureka中的application(即"SPRINGCLOUD-PROVIDER-DEPT")来得到一个具体的微服务的信息List<ServiceInstance> instances = client.getInstances("SPRINGCLOUD-PROVIDER-DEPT");for(ServiceInstance instance:instances){System.out.println(instance.getHost()+"\t"+instance.getPort()+"\t"+instance.getUri()+"\t"+instance.getServiceId());}return this.client;}}
1_6_2_2在启动类中添加@EnableDiscoveryClient注解
@SpringBootApplication
@EnableEurekaClient//在程序启动之后会自动注册到Eureka服务端中!通过http://localhost:7001/能进入Eureka界面能看见注册的Eureka
@EnableDiscoveryClient
public class DeptProvider_8001 {public static void main(String[] args) {SpringApplication.run(DeptProvider_8001.class,args);}
}
1_6_2_3进入http://localhost:8001/dept/discovery查看效果
实际上我们完全可以通过status链接跳转到discorery界面或者是swagger界面等其他链接,只需要修改
eureka.instance.status-page-url
地址就行。
server:port: 8001#springboot和数据库相关配置
spring:application:name: server-provider-8001 #本应用在Eureka中的Application名称datasource:username: rootpassword: 3333url: jdbc:mysql://localhost:3306/db01?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezeno=GMT%2B8driver-class-name: com.mysql.jdbc.Drivertype: com.alibaba.druid.pool.DruidDataSource
mybatis:mapper-locations: classpath:/mapper/DeptMapper.xml#Eureka的配置
eureka:client:service-url:defaultZone: http://localhost:7001/eureka/#Eureka Client注册到Eureka Server要用上这个地址instance:instance-id: provider_dept8001 #修改eureka中status的up的默认描述信息status-page-url: http://localhost:8001/dept/discovery #默认地址:http://desktop-8aqan37:8001/actuator/info##info配置:点击UP就会得到信息:{"app":{"name":"junjun-springcloud"},"company":{"name":"blog.junjun.com"}}
#info:
# app.name: junjun-springcloud
# company.name: blog.junjun.com
1_7搭建eureka集群环境
1_7_1复制eureka7001,生成7002,7003
1_7_2修改各个eureka服务器的主机名hostname,使得主机名唯一
1.把hostname和defaultZone修改一下,每个和其他所有eureka服务器相互注册。
2.要想搭配成集群环境,必须满足以下两个条件
(1)每台eureka服务器主机名唯一eureka.instance.hostname:
(2)每两个服务器service-url.defaultZone相互关联
实际上,eureka服务器集群原理就是注册中心相互注册,但是不开启检索服务的能力(fetch-registry: false)。
如果注册中心a的defaultZone为空或指向自己(不向b注册),注册中心b向a进行注册,那么注册信息是单向传递的(b会共享给a,a不会共享给b)参考文章。
3.测试结果:集群中所有服务器共享注册信息。即在一台eureka服务器上注册,另外两条也能显示注册信息。
--------7001的application.yml
server:port: 7001
eureka:instance:hostname: eureka7001.com #Eureka服务端的实例名称client:register-with-eureka: false # 表示是否想eureka注册中心注册自己,1,如果要注册的话得在defaultZone提供注册中心地址fetch-registry: false #表示是否从Eureka Server获取注册中心的服务信息,eureka服务端没有必要获取注册中心的注册信息,默认值都是trueservice-url:# 单机:defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/#集群(关联):defaultZone: http://localhost:7002/eureka/,http://localhost:7003/eureka/
--------7002的application.yml
server:port: 7002
eureka:instance:hostname: eureka7002.com #Eureka服务端的实例名称client:register-with-eureka: false # 表示是否想eureka注册中心注册自己,1,如果要注册的话得在defaultZone提供注册中心地址fetch-registry: false #表示是否从Eureka Server获取注册中心的服务信息,eureka服务端没有必要获取注册中心的注册信息,默认值都是trueservice-url:# 单机:defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/#集群(关联):defaultZone: http://localhost:7001/eureka/,http://localhost:7003/eureka/
--------7003的application.yml
server:port: 7003
eureka:instance:hostname: eureka7003.com #Eureka服务端的实例名称client:register-with-eureka: false # 表示是否想eureka注册中心注册自己,1,如果要注册的话得在defaultZone提供注册中心地址fetch-registry: false #表示是否从Eureka Server获取注册中心的服务信息,eureka服务端没有必要获取注册中心的注册信息,默认值都是trueservice-url:# 单机:defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/#集群(关联):defaultZone: http://localhost:7001/eureka/,http://localhost:7002/eureka/
1_7_3模拟多台独立服务器(域名)组成集群的效果:修改hosts中的域名映射关系
其实只要每个eureka服务器主机名不一样就能搭配成集群环境了,但是因为所有eureka服务器都部署在本地显得DS Replicas显示域名都是localhost。为了把eureka服务器做出区分,我们在hosts中修改域名映射关系来模拟在多台独立服务器(域名)组成集群的效果。要想让这两个url生效得在
C:\Windows\System32\drivers\etc\hosts
文档中添加域名映射关系
1.修改hosts域名关系映射表
2.修改defaultZone:注册中心地址。
server:port: 7001
eureka:instance:hostname: eureka7001.com #Eureka服务端的实例名称client:register-with-eureka: false # 表示是否想eureka注册中心注册自己,1,如果要注册的话得在defaultZone提供注册中心地址fetch-registry: false #表示是否从Eureka Server获取注册中心的服务信息,eureka服务端没有必要获取注册中心的注册信息,默认值都是trueservice-url:# 单机:defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/#集群(关联):defaultZone: http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
server:port: 7002
eureka:instance:hostname: eureka7002.com #Eureka服务端的实例名称client:register-with-eureka: false # 表示是否想eureka注册中心注册自己,1,如果要注册的话得在defaultZone提供注册中心地址fetch-registry: false #表示是否从Eureka Server获取注册中心的服务信息,eureka服务端没有必要获取注册中心的注册信息,默认值都是trueservice-url:# 单机:defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/#集群(关联):defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7003.com:7003/eureka/ #eureka7002.com等这三个会在hosts文档中添加这种映射关系
server:port: 7003
eureka:instance:hostname: eureka7003.com #Eureka服务端的实例名称client:register-with-eureka: false # 表示是否想eureka注册中心注册自己,1,如果要注册的话得在defaultZone提供注册中心地址fetch-registry: false #表示是否从Eureka Server获取注册中心的服务信息,eureka服务端没有必要获取注册中心的注册信息,默认值都是trueservice-url:# 单机:defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/#集群(关联):defaultZone: http://eureka7002.com:7002/eureka/, http://eureka7001.com:7001/eureka/#这三个会在hosts文档中添加这种映射关系
1_7_4 测试:使用服务器提供者8001来进行测试
1、先开启7001,7002,7003,http://localhost:7001/
再开启8001,注意8001的service-url:defaultZone: http://localhost:7001/eureka/
即仅在一台eureka服务器上注册,但是在eureka集群环境eureka服务器会进行注册信息同步.因此刷新http://localhost:7001/
、http://localhost:7002/
、http://localhost:7003/
后都能找到8001,那集群环境就算配置成功!
1_7_5将服务提供者向所以eureka服务器连通
2、然后我们会将服务提供者进行配置:
defaultZone:http://localhost:7001/eureka/,http://localhost:7002/eureka/,http://localhost:7003/eureka/
,使得服务提供者可以在任意一台eureka服务器上进行注册。
server:port: 8001
# mybatis的配置
mybatis:type-aliases-package: com.junjun.springcloud.pojomapper-locations: classpath:mybatis/mapper/*.xmlconfig-location: classpath:mybatis/mybatis-config.xml#spring和数据库的配置
spring:application:name: springcloud-provider-dept #本应用在Eureka中的名称(会变成大写)datasource:type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: org.gjt.mm.mysql.Driverurl: jdbc:mysql://localhost:3306/db01?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezeno=GMT%2B8username: rootpassword: 3333#Eureka的配置
eureka:client:service-url:defaultZone: http://localhost:7001/eureka/ #本机的7001,7002,7003端口可以访问Eurekainstance:instance-id: springcloud-provider-dept8001,springcloud-provider-dept8002,springcloud-provider-dept8003 #修改eureka中的默认描述信息
#info配置:点击UP就会得到信息:{"app":{"name":"junjun-springcloud"},"company":{"name":"blog.junjun.com"}}
info:app.name: junjun-springcloudcompany.name: blog.junjun.com
1_7_5配置服务端集群
(1)复制数据库生成完全一样的db02和db03,并修改datasource属性为当前数据库。
CREATE TABLE db02.dept LIKE db01.dept;
INSERT INTO db02.dept SELECT * FROM db01.dept;
CREATE TABLE db03.dept LIKE db01.dept;
INSERT INTO db03.dept SELECT * FROM db01.dept;
(2)创建多台服务提供者:复制springcloud-provider-dept-8001模块生成8002和8003
1.记得要修改每个服务提供者端口号
2.修改每个服务提供者所使用的数据库spring.datasource.url
3.修改每个服务提供者Eureka的配置,
修改defaultZone: http://localhost:7001/eureka/,http://localhost:7002/eureka/,http://localhost:7003/eureka/,使得服务提供者能够在任意一台eureka服务器上进行注册
修改instance-id,使得每台服务提供者的id都不同。
4.修改每个服务提供者自定义启动类的名称
【注意】
要保证三个服务器的spring.application.name是一样的哦,只有三台服务器的spring.application.name是一样的才能形成服务器集群,不然就不是同一个应用的服务器了。
1_8在客户端实现负载均衡
负载均衡的实现方式有两种,分别是
服务端负载均衡(nginx)
和客户端负载均衡(ribbon):
服务端负载均衡
:当浏览器向后台发出请求的时候,会首先向反向代理服务器发送请求,反向代理服务器会根据客户端部署的ip:port映射表以及负载均衡策略,来决定向哪台服务器发送请求,一般会使用到nginx反向代理技术。
客户端负载均衡
:当浏览器向后台发出请求的时候,客户端会向服务注册器(例如:Eureka Server),拉取注册到服务器的可用服务信息,然后根据负载均衡策略,直接命中哪台服务器发送请求。这整个过程都是在客户端完成的,并不需要一个独立的Ribbon服务器(反向代理服务器)的参与。
1_8_1 使用ribbon自带负载均衡算法:@LoadBalanced
在RestTemplate上使用@LoadBalanced,就能使得RestTemplate具有Ribbon的负载均衡的效果
-----------------------config/configBean
@Configuration
public class ConfigBean {//RestTemplate是一套接口,服务消费者都会通过RestTemplate来调用服务提供者的方法。@Bean@LoadBalanced//配置负载均衡,实现Ribbonpublic RestTemplate getRestTemplate(){return new RestTemplate();}
}
测试是否成功配置负载均衡
http://localhost/consumer/dept/list
【注意】我们不需要额外添加ribbon依赖,是因为spring-cloud-starter-eureka依赖带有spring-cloud-starter-netflix-eureka-client依赖,spring-cloud-starter-netflix-eureka-client自带了spring-cloud-starter-netflix-ribbon依赖。
1_8_2 使用ribbon实现自定义负载均衡算法
(1)自己编写一个Rule类继承AbstractLoadBalancerRule,并添加choose(ILoadBalancer lb, Object key) 方法。
---------------------com.myrule.junRandomRule.java(注意:没有和启动类在同一级目录)
package com.junjun.myrule;import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server;import java.util.List;
import java.util.concurrent.ThreadLocalRandom;@Component
public class junRandomRule extends AbstractLoadBalancerRule {private int total=0;private int currentIndex=0;public junRandomRule() {}//@SuppressWarnings({"RCN_REDUNDANT_NULLCHECK_OF_NULL_VALUE"})public Server choose(ILoadBalancer lb, Object key) {if (lb == null) {return null;} else {Server server = null;while(server == null) {if (Thread.interrupted()) {return null;}List<Server> upList = lb.getReachableServers();//获取活着的服务List<Server> allList = lb.getAllServers();//获取所有的服务int serverCount = allList.size();//serverCount是所有服务的数量if (serverCount == 0) {return null;}
// int index = this.chooseRandomInt(serverCount);//随机获取一个序号
// server = (Server)upList.get(index);//从活着的服务中获取对应序号的服务
////*******************这里是我改写的算法**************************************if(total<5){server = upList.get(currentIndex);total++;}else{total=0;currentIndex++;if(currentIndex>=upList.size()){currentIndex=0;}server=upList.get(currentIndex);}//*******************我的部分结束**************************************if (server == null) {Thread.yield();} else {if (server.isAlive()) {return server;}server = null;Thread.yield();}}return server;}}protected int chooseRandomInt(int serverCount) {return ThreadLocalRandom.current().nextInt(serverCount);}public Server choose(Object key) {return this.choose(this.getLoadBalancer(), key);}public void initWithNiwsConfig(IClientConfig clientConfig) {}
}
(2)将该策略添加到项目中(在启动类上使用@RibbonClient)
如果把rule类放在和DeptConsumer_80同一目录下,那么该负载均衡算法是能够被本服务器扫描到的,因此@RibbonClient都不用写了(当然,@Component注册bean还是要写的)。
@SpringBootApplication
@EnableEurekaClient
//1、当客户端存在自定义Ribbon和原有Ribbon时,自定义会覆盖原有Ribbon
// 2、MyRule不应该在@ComponentScan中(所以不应该在application同级目录下),否则会被所有RibbonClients共享,所有RibbonClients都会采取这个策略
@RibbonClient(name = "SPRINGCLOUD-PROVIDER-DEPT",configuration = junRandomRule.class)
public class DeptConsumer_80 {public static void main(String[] args) {SpringApplication.run(DeptConsumer_80.class);}
}
(3)测试
本负载均衡的效果是每个服务器都能5次,5次后就换一个服务器
1_8_3 使用nginx实现负载均衡思路图
1_8_4 使用openFeign实现负载均衡
1_9 使用feign替代RestTemplate(其内部集成了RestTemplate)
1.feign不是做负载均衡的,feign只是集成了ribbon(负载均衡还是feign内置的ribbon做)。feign的作用的替代RestTemplate,这会导致性能降低,但是可以使代码可读性很强。
2.狂神的视频是把service层发在springcloud-api中,我觉得不是很懂,就自己放在了消费者里面了,并精简了config文件夹,不知道我这样做有没有什么问题,后期了解了原理再探讨这个问题吧。
3.若把service放在springcloud-api中,需要我们把依赖放在springcloud-api中,而springcloud-consumer-dept-feign
就不需要添加这个依赖了。
1_9_1 复制然后创建一个新的服务消费者model用来测试feign
复制
springcloud-consumer-dept-80
,创建springcloud-consumer-dept-feign
1_9_2 在原来依赖的基础上添加feign依赖
<dependencies><!-- 添加feign依赖--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId><!-- <version>1.4.6.RELEASE</version>--></dependency>
<!-- Eureka依赖添加--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-eureka</artifactId><version>1.4.6.RELEASE</version></dependency><dependency><groupId>org.example</groupId><artifactId>springcloud-api</artifactId><version>1.0-SNAPSHOT</version></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>
1_9_3 修改启动类名为FeignDeptConsumer_80,并添加注解@EnableFeignClients扫描FeignClient
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients(basePackages = {"com.junjun.springcloud"})//这里是扫描springcloud_api模块中的DeptClientService作为Feign的接口类
public class FeignDeptConsumer_80 {public static void main(String[] args) {SpringApplication.run(FeignDeptConsumer_80.class);}
}
1_9_4在Fiegn所在的服务消费者中添加service层(使用@FeignClient)
----------------service/DeptClientService
@Component
@FeignClient(value= "SPRINGCLOUD-PROVIDER-DEPT")//这个接口将会被动态代理实现,参考内容是服务提供者("SPRINGCLOUD-PROVIDER-DEPT")中的mapper.xml???
public interface DeptClientService {@GetMapping("/dept/add")public boolean addDept(Dept dept);@GetMapping("/dept/get/{id}")public Dept queryById(@PathVariable("id") Long id);@GetMapping("/dept/list")public List<Dept> queryAll();
}
1_9_5在controller不使用RestTemplate,而是使用DeptClientService来调用服务提供者。
@RestController
public class DeptConsumerController {@Qualifier("com.junjun.springcloud.service.DeptClientService")//有多个DeptClientService的bean,所以要用@Qualifier@Autowiredprivate DeptClientService service;@RequestMapping("/consumer/dept/add")public boolean add(@RequestBody Dept dept){return this.service.addDept(dept);}@RequestMapping("/consumer/dept/get/{id}")public Dept get(@PathVariable("id") Long id){return this.service.queryById(id);}@RequestMapping("/consumer/dept/list")public List<Dept> list(){return this.service.queryAll();}
}
1_9_6测试
进入
http://localhost/consumer/dept/list
,多次刷新查看负载均衡的策略(默认是轮询)。
1_10分布式系统的延迟和容错处理方式
1.服务熔断:某个服务超时或者异常,会引起服务熔断(在服务端实现)
2.服务降级:从服务端整体考虑,关掉某些服务(在客户端实现)
3.服务雪崩:
Hytrix实现服务熔断(已过时)
1_10_1复制springcloud-provider-dept-8001生成一个新的服务提供者:springcloud-provider-dept-hystrix-8001
1_10_2添加Hystrix依赖到原有依赖中
<dependencies><!-- 添加hystrix依赖--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-hystrix</artifactId><version>1.4.6.RELEASE</version></dependency><!-- actuator完善监控信息--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><!-- Eureka依赖添加--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-eureka</artifactId><version>1.4.6.RELEASE</version></dependency><!-- 我们需要拿到api模块中的实体类,所以需要配置api module--><dependency><groupId>org.example</groupId><artifactId>springcloud-api</artifactId><version>1.0-SNAPSHOT</version></dependency><!-- 2.junit--><dependency><groupId>junit</groupId><artifactId>junit</artifactId><scope>test</scope></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId></dependency><!-- logback是log4j的日志组件--><dependency><groupId>ch.qos.logback</groupId><artifactId>logback-core</artifactId></dependency><!-- Mybatis依赖:通过Mybatis管理mysql数据库--><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId></dependency><!-- springboot的web项目的必备依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- springboot-test:@SpringBootTest注解的所在的依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-test</artifactId></dependency><!-- jetty--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jetty</artifactId></dependency><!-- 热部署工具:devtools--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId></dependency></dependencies>
1_10_3在application.yml中修改instance-id,方便区分
server:port: 8001
# mybatis的配置
mybatis:type-aliases-package: com.junjun.springcloud.pojomapper-locations: classpath:mybatis/mapper/*.xmlconfig-location: classpath:mybatis/mybatis-config.xml#spring的配置
spring:application:name: springcloud-provider-dept #本应用在Eureka中的名称(会变成大写)datasource:type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: org.gjt.mm.mysql.Driverurl: jdbc:mysql://localhost:3306/db01?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezeno=GMT%2B8username: rootpassword: 3333#Eureka的配置
eureka:client:service-url:defaultZone: http://localhost:7001/eureka/,http://localhost:7002/eureka/,http://localhost:7003/eureka/ #本机的7001,7002,7003端口可以访问Eurekainstance:instance-id: springcloud-provider-hystrix-dept8001 #修改eureka中的默认描述信息
#info配置:点击UP就会得到信息:{"app":{"name":"junjun-springcloud"},"company":{"name":"blog.junjun.com"}}
info:app.name: junjun-springcloudcompany.name: blog.junjun.com
1_10_4修改启动类名为:DeptProviderHystrix_8001.java,并添加@EnableCircuitBreaker
@EnableCircuitBreaker是将@HystrixCommand注册到bean中去
@SpringBootApplication
@EnableEurekaClient//在程序启动之后会自动注册到Eureka服务端中!通过http://localhost:7001/能进入Eureka界面能看见注册的Eureka
@EnableDiscoveryClient
@EnableCircuitBreaker//添加对熔断注解的支持(即将@HystrixCommand注册到bean中去)。
public class DeptProviderHystrix_8001 {public static void main(String[] args) {SpringApplication.run(DeptProviderHystrix_8001.class,args);}
}
1_10_5修改controller层(添加处理错误的功能)
@RestController
public class DeptController {@Autowiredprivate DeptService deptService;@GetMapping("/dept/get/{id}")@HystrixCommand(fallbackMethod = "hystrixGet")//失败就会调用hystrixGet方法public Dept get(@PathVariable("id") Long id){Dept dept = deptService.queryById(id);if(dept==null){throw new RuntimeException("id=>"+id+"没有对应的信息");}return dept;}//备选方案public Dept hystrixGet(@PathVariable("id") Long id){System.out.println("*****************失败了*************************");return new Dept().setDeptno(id).setDname("id=>"+id+"没有对应的信息-@Hystrix").setDb_source("no this database in MySQL");}
}
1_10_6测试http://localhost/consumer/dept/get/6
1.注意我们只写了add函数,没写list函数,所以不要用list来测试
2.可能会出现服务器崩坏的现象,这时候一个一个重启服务器就行 。
feign实现服务降级
1_10_7在feign实现负载均衡的基础上添加一个类
package com.junjun.springcloud.service;import com.junjun.springcloud.pojo.Dept;
import feign.hystrix.FallbackFactory;
import org.springframework.stereotype.Component;import java.util.List;
//降级
@Component
public class DeptClientServiceFallbackFactory implements FallbackFactory {@Overridepublic DeptClientService create(Throwable throwable) {return new DeptClientService() {@Overridepublic boolean addDept(Dept dept) {return false;}@Overridepublic Dept queryById(Long id) {return new Dept().setDeptno(id).setDname("id=>"+id+"没有对应的信息,客户端提供了降级的信息,这个服务现在已经被关闭了").setDb_source("没有数据");}@Overridepublic List<Dept> queryAll() {return null;}};}}
1_10_8给servicec层的接口添加服务降级画面显示(fallbackFactory)
提供服务降级提示的服务器是哪个呢??
//通过Feign来指定熔断降级的操作
@Component
@FeignClient(value= "SPRINGCLOUD-PROVIDER-DEPT",fallbackFactory = DeptClientServiceFallbackFactory.class)//这个接口将会被动态代理实现,参考内容是服务提供者("SPRINGCLOUD-PROVIDER-DEPT")中的mapper.xml???
public interface DeptClientService {@GetMapping("/dept/add")public boolean addDept(Dept dept);@GetMapping("/dept/get/{id}")public Dept queryById(@PathVariable("id") Long id);@GetMapping("/dept/list")public List<Dept> queryAll();
}
1_10_9测试
熔断监控DashBoard监控请求(流量)
1_10_10新建一个模块:springcloud-consumer-hystrix-dashboard
,并往dashboard模块中添加依赖
<dependencies>
<!-- 导入Hystrix和他的监控页面这两个依赖1.服务端必须要有actuator才能监控得到
--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-hystrix</artifactId><version>1.4.6.RELEASE</version></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-hystrix-dashboard</artifactId><version>1.4.6.RELEASE</version></dependency><!-- Ribbon依赖添加--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-ribbon</artifactId><version>1.4.6.RELEASE</version></dependency><!-- Eureka依赖添加--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-eureka</artifactId><version>1.4.6.RELEASE</version></dependency><dependency><groupId>org.example</groupId><artifactId>springcloud-api</artifactId><version>1.0-SNAPSHOT</version></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>
1_10_11设置dashboard模块的端口
server:port: 9001
1_10_12配置启动类
@SpringBootApplication
@EnableHystrixDashboard//开启DashBoard
public class DeptConsumerDashboard_9001 {public static void main(String[] args) {SpringApplication.run(DeptConsumerDashboard_9001.class);}
}
1_10_13在springcloud-provider-dept-hystrix-8001
的启动类上添加servlet
使用
springcloud-provider-dept-8001
就不行,无论是添加依赖还是添加@EnableCircuitBreaker、servlet都不行。
@SpringBootApplication
@EnableEurekaClient//在程序启动之后会自动注册到Eureka服务端中!通过http://localhost:7001/能进入Eureka界面能看见注册的Eureka
@EnableDiscoveryClient
@EnableCircuitBreaker//添加对熔断注解的支持(即将@HystrixCommand注册到bean中去)。
public class DeptProviderHystrix_8001 {public static void main(String[] args) {SpringApplication.run(DeptProviderHystrix_8001.class,args);}@Bean//增加一个servletpublic ServletRegistrationBean hystrixMetricsStreamServlet(){ServletRegistrationBean registrationBean = new ServletRegistrationBean(new HystrixMetricsStreamServlet());registrationBean.addUrlMappings("/actuator/hystrix.stream");return registrationBean;}
}
1_10_14测试
进入
http://localhost:9001/hystrix
。如果能实现上面界面,就可以进入dashboard界面了。
1_11路由网关Zuul(已过时)
1_11_1添加依赖
<dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-zuul</artifactId><version>1.4.6.RELEASE</version></dependency><!-- 导入Hystrix和他的监控页面这两个依赖1.服务端必须要有actuator才能监控得到--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-hystrix</artifactId><version>1.4.6.RELEASE</version></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-hystrix-dashboard</artifactId><version>1.4.6.RELEASE</version></dependency><!-- Ribbon依赖添加--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-ribbon</artifactId><version>1.4.6.RELEASE</version></dependency><!-- Eureka依赖添加--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-eureka</artifactId><version>1.4.6.RELEASE</version></dependency><dependency><groupId>org.example</groupId><artifactId>springcloud-api</artifactId><version>1.0-SNAPSHOT</version></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>
1_11_2 配置application.yml
server:port: 9527spring:application:name: springcloud-zuul#Eureka的配置
#Eureka的配置
eureka:client:service-url:defaultZone: http://localhost:7001/eureka/,http://localhost:7002/eureka/,http://localhost:7003/eureka/ #本机的7001,7002,7003端口可以访问Eurekainstance:instance-id: zuul9527.com #修改eureka中的默认描述信息prefer-ip-address: trueinfo:app.name: junjun-springcloudcompany.name: blog.junjunstudy.com
1_11_3修改域名映射关系:C:\Windows\System32\drivers\etc\hosts
1_11_4配置启动类ZuulApplication_9527
@SpringBootApplication
@EnableZuulProxy
public class ZuulApplication_9527 {public static void main(String[] args) {SpringApplication.run(ZuulApplication_9527.class);}
}
1_11_5测试
访问
http://www.junjunstudy.com:9527/springcloud-provider-dept/dept/get/2
1_11_5实现域名伪装:修改9527一下application.yml的zuul配置,并测试
server:port: 9527spring:application:name: springcloud-zuul#Eureka的配置
#Eureka的配置
eureka:client:service-url:defaultZone: http://localhost:7001/eureka/,http://localhost:7002/eureka/,http://localhost:7003/eureka/ #本机的7001,7002,7003端口可以访问Eurekainstance:instance-id: zuul9527.com #修改eureka中的默认描述信息prefer-ip-address: trueinfo:app.name: junjun-springcloudcompany.name: blog.junjunstudy.comzuul:#实现域名伪装:用mydept代替springcloud-provider-deptroutes: mydept.serviceId: springcloud-provider-deptmydept.path: /mydept/** #使得原来的服务器名称不可访问服务器ignored-services: springcloud-provider-dept#ignored-services: "*" #忽略所有,只有通过mydept才能访问得到。
用代理名称代替服务提供者的名称
完整版如下:
server:port: 9527spring:application:name: springcloud-zuul#Eureka的配置
#Eureka的配置
eureka:client:service-url:defaultZone: http://localhost:7001/eureka/,http://localhost:7002/eureka/,http://localhost:7003/eureka/ #本机的7001,7002,7003端口可以访问Eurekainstance:instance-id: zuul9527.com #修改eureka中的默认描述信息prefer-ip-address: trueinfo:app.name: junjun-springcloudcompany.name: blog.junjunstudy.comzuul:#实现域名伪装:用mydept代替springcloud-provider-deptroutes:mydept.serviceId: springcloud-provider-deptmydept.path: /mydept/**#使得原来的服务器名称不可访问服务器ignored-services: "*" #忽略所有,只有通过mydept才能访问得到。prefix: /junjun #设置统一的访问前缀`
访问
http://www.junjunstudy.com:9527/junjun/mydept/dept/get/2
1_12config
Git环境配置
1_12_1配置Git项目环境
【码云环境配置】
包括:1.官网下载Git工具 2.更改Git姓名和邮箱 3.在本机上配置公钥
1_12_2在git码云上创建一个项目,并获取到本地。然后新建一个application.yml文档,并添加上以下内容。
spring:profiles: active: dev---
spring:profiles: devapplication:name: springcloud-config-dev---
spring:profiles: testapplication:name: springcloud-config-test
1_12_3上传到git远程服务器。
配置config服务端并连接git的远程仓库
1_12_4导入依赖
<dependencies>
<!-- springcloud-config--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-config-server</artifactId><version>2.1.1.RELEASE</version></dependency>
<!-- Eureka--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-eureka</artifactId><version>1.4.6.RELEASE</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>
</dependencies>
1_12_5配置application.yml
server:port: 3344
spring:application:name: springcloud-config-server#连接远程仓库cloud:config:server:git:uri: https://gitee.com/junjunlllll/spring-config.git #这是https的地址,不是SSH
1_12_6 配置启动类
@SpringBootApplication
@EnableConfigServer //
public class Config_Server_3344 {public static void main(String[] args) {SpringApplication.run(Config_Server_3344.class);}
}
1_12_7测试是否联通
通过git进行远程资源 配置 本地项目。
1_12_8在git项目目录下添加一个yml文档。
在git上部署多套环境,而我们只要修改spring.profiles就能配置git上对应配置(如名字,端口号)。
spring:profiles:active: dev
---
server:port: 8201spring:profiles: devapplication:name: springcoud-provider-dept
eureka:client:service-url:defaultZone: http://eureka7001.com:7001/eureka/
---
server:port: 8202spring:profiles: testapplication:name: springcoud-provider-dept
eureka:client:service-url:defaultZone: http://eureka7001.com:7001/eureka/
1_12_9 push到远程服务器
1_12_10 创建springcloud-config-client-3355模块,并配置依赖
<dependencies><!-- springcloud-config--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-config</artifactId><version>2.1.1.RELEASE</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency></dependencies>
1_12_11 配置配置文件
bootstrap系统级别的配置,而application是用户级别的配置
--------------bootstrap.yml
#bootstrap系统级别的配置,而application是用户级别的配置
spring:cloud:config:profile: test #激活了dev,所以这个client的端口号是8201,如果激活test该模块的端口号就是8202name: config-client #从git上读取的资源名称(我们在git上有一个config-client.yml),不需要后缀label: masteruri: http://localhost:3344
------------application.yml
spring:application:name: springcloud-config-client-3355
1_12_12启动类和controller层
-----------ConfigClient_3355启动类
@SpringBootApplication
public class ConfigClient_3355 {public static void main(String[] args) {SpringApplication.run(ConfigClient_3355.class);}
}
----------------controller层
@RestController
public class ConfigClientControler {@Value("${spring.application.name}")private String application;@Value("${eureka.client.service-url.defaultZone}")private String eurekaServer;@Value("${server.port}")private String port;@RequestMapping("/config")public String getConfig(){return "application:"+application+"eurekaServer:"+eurekaServer+"port:"+port;}
}
1_12_12访问http://localhost:8201/config
测试
远程配置资源项目(这里以7001服务器为例)
前提是配置服务器3344成功,我们将通过3344获取资源文件并配置资源
1_12_13 配置并上传远程资源
---------代码如下
spring:profiles:active: dev
---
server:port: 7001
spring:profiles: devapplication:name: springcloud-config-eureka
eureka:instance:hostname: eureka7001.com #Eureka服务端的实例名称client:register-with-eureka: false # 表示是否想eureka注册中心注册自己fetch-registry: false #false表示自己为注册中心(开集群需要注册自己)service-url:defaultZone: http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/ #eureka7002.com等这三个会在hosts文档中添加这种映射关系
---
server:port: 7001spring:profiles: testapplication:name: springcloud-config-eurekaeureka:instance:hostname: eureka7001.com #Eureka服务端的实例名称client:register-with-eureka: false # 表示是否想eureka注册中心注册自己fetch-registry: false #false表示自己为注册中心(开集群需要注册自己)service-url:defaultZone: http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/ #eureka7002.com等这三个会在hosts文档中添加这种映射关系
1_12_14 创建一个7001模块,并导入依赖
<dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-config</artifactId><version>2.1.1.RELEASE</version></dependency><!-- 导入Eureka包--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-eureka-server</artifactId><version>1.4.6.RELEASE</version></dependency><!-- 热部署工具--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId></dependency></dependencies>
1_12_15创建bootstrap.yml和application.yml(核心)
--------------bootstrapyml
spring:cloud:config:name: config-eureka #这是远程资源的名称label: masterprofile: devuri: http://localhost:3344
spring:application:name: springcloud-config-eureka-7001
1_12_16 配置启动类
@SpringBootApplication
@EnableEurekaServer//EnableEurekaServer是开启服务器的启动类,他能够接受别人注册进来~
public class EurekaServer_7001 {public static void main(String[] args) {SpringApplication.run(EurekaServer_7001.class);}
}
1_12_17测试
-----------------------springcloud新技术-----------------------
在上述中很多技术都已经过时不再更新了,所以我们要用到新的技术
一、Nacos:服务中心+配置中心
1、Nacos作为服务中心
Nacos(Naming configuration service)是一个服务发现、配置管理、服务管理平台。所以Nacos=Eureka+Config+Bus。
1.1 下载、启动nacos
**********************1.下载
下载地址
**********************2.启动nacos,并登入
1、在bin中双击startup.cmd就行。
2、然后访问http://localhost:8848/nacos/index.html
3、通过账号密码:nacos/nacos登录。
4、右上角切换中文
1.2 nacos替代eureka作为服务注册中心
在服务的yml中spring☁️nacos:discovery:server-addr:localhost:8848。来在nacos中注册。
(1) 在nacos客户端(如服务提供者、服务消费者)上添加依赖
<dependencies>
<!-- springboot版本为2.3.9.RELEASE--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!-- nacos--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId><version>2.2.0.RELEASE</version></dependency></dependencies>
【注意】
springboot版本低于nacos版本会出现异常;
(2) 对eureka客户端进行配置
server:port: 9001spring:application:name: nacos-test #本应用在nacos的名称cloud:nacos:discovery:server-addr: localhost:8848
(3)配置启动类
@EnableDiscoveryClient
@SpringBootApplication
public class DemoApplication {public static void main(String[] args) {SpringApplication.run(DemoApplication.class, args);}}
(4)在nacos中发现该客户端成功
这可比Eureka方便多了,不需要自己手动搭建Eureka服务端。
2.1.3 nacos替代Config作为服务配置中心
2.1.4 nacos集群和持久化配置
2、Nacos作为配置中心
GateWay网关
2.1 GateWay+Eureka
网关有两种常用的类型:zool和GateWay。使用一种简单有效的方法来对API进行路由、过滤、熔断、限流、重试。
Springcloud GateWay是基于WebFlux框架实现的,而WebFlux框架底层是使用了高性能的Reactor模式的框架Netty。
2.1.1 GateWay实现路由效果
(1) 添加依赖
<dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency><!-- Eureka依赖添加--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-eureka</artifactId><version>1.4.6.RELEASE</version></dependency>
【注意】
不能要spring-boot依赖不然会报错
(2)添加配置文件
------------------------------方法一:在application.yml中进行配置
server:port: 9527
#我们往往不想暴露我们的服务器ip和端口,因此用GateWay的9527端口来掩饰
spring:application:name: cloud-gatewaycloud:gateway:routes:- id: payment_routh #第一个路由,路由id要保证唯一uri: http://localhost:8001 #匹配后提供服务的路由地址predicates: #断言,与uri路径进行匹配- Path=/dept/**- id: pay #第二个路由,路由id要保证唯一uri: http://localhost:8001predicates:- Path=/aaa/**eureka:instance:hostname: cloud-gateway-serviceclient:service-url:register-with-eureka: truefetch-registry: truedefaultZone: http://localhost:7001/eureka/,http://localhost:7002/eureka/,http://localhost:7003/eureka/ #本机的7001,7002,7003端口可以访问Eureka
------------------------------方法二:在config/Gatewaay中使用配置bean的方式进行路由设置
@Configuration
class GatewayConfig {@Beanpublic RouteLocator routes(RouteLocatorBuilder builder) {RouteLocatorBuilder.Builder routes = builder.routes();routes.route("path_route1",r->r.path("/guonei").uri("http://news.baidu.com/guonei")).build();//访问地址http://localhost:9527/guonei时会自动转发到地址:http://news.baidu.com/guoneireturn routes.build();}
}
(3)配置启动类
@EnableEurekaClient
@SpringBootApplication
public class GateWay9527 {public static void main(String[] args) {SpringApplication.run(GateWay9527.class,args);}
}
(4)测试:实现路由功能
http://localhost:9527/dept/list
发现即使是使用http://localhost:8001/dept/list也能成功访问。
2.1.2 Gateway配置动态路由,实现负载均衡
1、默认情况下,Gateway会根据注册中心的服务列表,以服务中心(eureka,nacos)上的服务名为路径创建动态路由进行转发,从而实现动态路由功能,实现服务器的负载均衡(默认轮询策略)。
(1)在2.1.1基础上更改配置文件
server:port: 9527
#我们往往不想暴露我们的服务器ip和端口,因此用GateWay的9527端口来掩饰
spring:application:name: cloud-gatewaycloud:gateway:discovery:locator:enabled: true #开启Gateway从注册中心动态创建路由的功能,利用微服务名进行路由routes:- id: payment_routh #第一个路由,路由id要保证唯一
# uri: http://localhost:8001 #匹配后提供服务的路由地址uri: lb://springcloud-provider-dept #1、lb是指loaderBalance的意思 2、springcloud-provider-dept是服务提供者集群的spring:application:namepredicates: #断言,与uri路径进行匹配- Path=/dept/**- id: pay #第二个路由,路由id要保证唯一
# uri: http://localhost:8001uri: lb://springcloud-provider-dept #1、lb是指loaderBalance的意思 2、springcloud-provider-dept是服务提供者集群的spring:application:namepredicates:- Path=/aaa/**eureka:instance:hostname: cloud-gateway-serviceclient:service-url:register-with-eureka: truefetch-registry: truedefaultZone: http://localhost:7001/eureka/,http://localhost:7002/eureka/,http://localhost:7003/eureka/ #本机的7001,7002,7003端口可以访问Eureka
(2) 测试负载均衡效果
2.1.2 Gateway如何自定义负载均衡策略呢
2.1.3 Gateway的Predicate
Spring Cloud Gateway有很多内置工厂Route Predicate Factory
server:port: 9527
spring:application:name: cloud-gatewaycloud:gateway:discovery:locator:enabled: true #开启Gateway从注册中心动态创建路由的功能,利用微服务名进行路由routes:- id: payment_routh #第一个路由,路由id要保证唯一
# uri: http://localhost:8001 #匹配后提供服务的路由地址uri: lb://springcloud-provider-dept #1、lb是指loaderBalance的意思 2、springcloud-provider-dept是服务提供者集群的spring:application:namepredicates: #断言,满足以下条件才会成功通过gateway把请求发送给服务器。- Path=/dept/** #地址匹配要正确- After=2020-10-12T16:51:37.485+08:00[Asia/Shanghai] #时间满足在2020-10-12T16:51:37之后- Cookie=username,zzyy #Cookie里面有个键值对,第一个参数是key:username,第二个参数是value:zzyy- Header=X-Request-Id,\d+ #对请求头进行匹配,value:\d+是为整数的正则表达式- id: pay
# uri: http://localhost:8001uri: lb://springcloud-provider-dept predicates:- Path=/aaa/**eureka:instance:hostname: cloud-gateway-serviceclient:service-url:register-with-eureka: truefetch-registry: truedefaultZone: http://localhost:7001/eureka/,http://localhost:7002/eureka/,http://localhost:7003/eureka/ #本机的7001,7002,7003端口可以访问Eureka
测试效果
2.1.4 GateWay的filter
Gateway自带的filter
使用自定义filter(全局GlobalFilter)
************filter/MyLoGateWayFilter
@Component
@Slf4j//这是lombok中的依赖. import lombok.extern.slf4j.Slf4j;
public class MyLoGateWayFilter implements GlobalFilter, Ordered {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {log.info("*************************com in MyLogGateWayFilter:"+new Date());String username = exchange.getRequest().getQueryParams().getFirst("username");if(null==username){log.info("***************不合法,用户名为null");exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);return exchange.getResponse().setComplete();}return chain.filter(exchange);}@Overridepublic int getOrder() {//日志顺序return 0;}
}
测试
2.2 Nacos+Eureka
2.2.1
【附加】springcloud原理和思想
CAP理论
C:
Consistency
一致性:读写(在同一个集群中的不同服务器上)内容保存一致。不存在在server1写完后,在server2读取的却是旧数据>A:Availability
可用性:只要我对服务器,发送请求,服务器必须对我进行相应,保证服务器一直是可用的。
P:Partition tolerance
,分区容错::分布式的服务器之间的数据不能同步。
为什么CAP只能达到 CP 或者 AP?
不懂!eureka是基于ap的。zookeeper是基于cp的。所有,eureka各个节点完全平等,当有些节点坏掉时,剩余节点还是可以提供注册和查询服务,因此eureka一定能得到数据,但是不一定是最新的;而zookeeper得到的数据一定是最新的,但是不一定能成功得到数据:当某些节点坏掉时,我们就不能访问了。
ribbon:客户端负载均衡的工具
ribbon是为客户端提供简单的负载均衡(LB,LoadBalancer)的算法。常见的负载均衡算法:随机 轮询 最少响应比。
常见的负载均衡软件:Nginx
,Lvs
,Apache+Tomcat
负载均衡:为请求分配集群中的服务器
负载均衡的类别:1、集中式 (如Nginx反向代理服务器)2、进程式(将LB集成到消费方如上面的7001)
springcloud 学习项目相关推荐
- SpringCloud学习笔记(1)- Spring Cloud Alibaba
文章目录 SpringCloud学习笔记(1)- Spring Cloud Alibaba 服务治理 Nacos 服务注册 Nacos 服务发现与调用 Ribbon 负载均衡 Sentinel 服务限 ...
- SpringCloud学习笔记(1)- Spring Cloud Netflix
文章目录 SpringCloud学习笔记(1)- Spring Cloud Netflix 单体应用存在的问题 Spring Cloud Eureka Eureka Server代码实现 Eureka ...
- SpringCloud学习系列之七 ----- Zuul路由网关的过滤器和异常处理
前言 在上篇中介绍了SpringCloud Zuul路由网关的基本使用版本,本篇则介绍基于SpringCloud(基于SpringBoot2.x,.SpringCloud Finchley版)中的路由 ...
- SpringCloud学习笔记(十四)Zuul网关
专辑目录:SpringCloud学习日志 网关的概念: 我举个例子,我们到银行取钱,但是我们不能自己到金库里去拿钱,而是通过柜台服务员取钱.这时候柜台服务员就是网关,如果你没有存折和密码(相当于账号和 ...
- 10个Spring Boot 优秀学习项目
10个Spring Boot 优秀学习项目 10个SpringBoot项目分享(好像多了一个项目) 一.mall (虽然培训机构已经把电商推广了烂大街了,但技术还是可以学习的) 二.Cloud-Pla ...
- SpringCloud学习笔记(十二)基于Hystrix解决雪崩效应
专辑目录:SpringCloud学习日志 什么是雪崩效应? 当请求数量远超出服务器承受能力或者服务器无法再处理请求时,导致请求等待时间比较久,也就是平常说的卡.由于微服务是利用RPC相互请求的,所以可 ...
- 开源的13个Spring Boot 优秀学习项目
开源的13个Spring Boot 优秀学习项目!超53K星,一网打尽! 原创: 徐刘根 Java后端技术 5月19日 Spring Boot 算是目前 Java 领域最火的技术栈了,也是Java开发 ...
- SpringCloud学习Day1
这SpringCloud学习 1.基本的杂乱概念 CAP 2.SpringCloud概述 2.1 微服务中的相关概念 2.1.1 服务注册与发现 2.1.2 负载均衡 2.1.3 熔断 2.1.4 链 ...
- SpringCloud学习记录 | 第十篇:Hystrix DashBoard 实时图像监控界面(豪猪哥)
一.Hystrix DashBoard Hystrix提供了准实时的调用监控(Hystrix Dashboard),Hystrix会持续记录所有的通过Hystrix发起的请求执行信息,并以统计报表和图 ...
最新文章
- eclipse下的spring环境配置
- mysql主从架构搭建_MySQL主从架构搭建
- 2.1.1 Speed Limit
- Android Studio使用Google Flutter完整教程
- 初识Ildasm.exe——IL反编译的实用工具(转自Youngman)
- python 合并word文件,在Python上的WordCloud中,我想合并两种语言
- c语言程序设计的几种循环,C语言程序设计教案 第六章 循环程序设计.doc
- 谷歌浏览器中打开IE
- windows server2008 r2 下启用 sqlserver 2008的远程连接
- 失意时,你是怎么救自己的?
- Builder 模式在 Guava 中的应用
- ModelAttribue注解的使用
- 实验室耗材管理系统,医院各科室如何进行耗材管理
- STM32智能锁指纹锁密码锁WIFI远程开锁微信小程序临时密码源码PCBA方案
- anywhere无法获取服务器响应,使用Chat Anywhere可能出现的问题与解决方法
- SpringBoot —— 实现邮件、短信的发送功能
- python判断性别_惊呆|根据三围数据判断出用户性别竟是python使用逻辑回归算法搞的鬼!...
- 30天自制操作系统第10天harib07d
- LeetCode 分类练习(四):查找2
- idea 在创建maven 时出现报错org.codehaus.plexus.component.repository.exception.ComponentLookupException:
热门文章
- MIL-STD-1553B
- 关于带新人和作新人。
- mysql中堆和栈_堆和栈 - 矮油~ - 博客园
- 公开讲座笔记 | 雷达学报 雷达系统微课 - 第三讲 相控阵雷达 与 “1+1=2“
- 老男孩39期决心书——刘浩海
- 数组是否包含某个元素
- python 自动点击网页上按钮_python selenium自动化(一)点击页面链接测试
- android播放视频控件,视频播放控件VideoView的基本使用
- ppt技巧一四步法调整PPT
- ICPC2017香港赛区游记