SpringCloud
微服务概述 微服务是什么? 微服务化的核心就是将传统的一站式应用根据业务拆分成一个一个的服务,彻底地去耦合化。每一个微服务提供单个业务功能的服务,一个服务做一件事。从技术角度来看就是一种小儿独立的处理过程,类似于进程的概念,能够自行单独启动或者销毁,用于自己独立的数据库。
微服务与微服务架构 微服务 强调的是服务的大小,它关注的是一个个的个体,每个个体完成一个具体的任务或者技能。从狭义上来看,例如集成开发工具里面用maven开发的一个个独立的小moudle,它具体是使用springboot开发的一个小模块,专业的事情交给专业的模块来做,一个模块就做这一件事
微服务架构 是一种架构模式,它提倡将单一应用程序划分成一组小的服务,服务之间互相协调、互相配合,为用户提供最终价值。每个服务运行在其独立的进程中,通常是基于HTTP协议的RESTFUL API。另外,应当尽量避免统一的、集中式的服务管理机制。
微服务优缺点 优点 1.微服务只是业务逻辑的代码,不会和HTML,CSS或其他界面组件混合
2.每个微服务都有自己的存储能力,可以有自己的数据库或统一的数据库
3.微服务能够被小团队单独开发
4.微服务能使用不同的语言开发,允许利用融合最新的技术
5.易于和第三方集成,微服务允许容易且灵活的方式集成自动部署,通过持续集成工具,如Jenkins,Hudson,bamboo
6.开发简单、开发效率提高,一个服务可能就是专一的只干一件事
缺点 服务间通信成本
数据一致性
开发人员要处理分布式系统的复杂性
性能监控
多服务运维难度,随着服务的增加,运维的压力也在增加
微服务技术栈有哪些 多种技术的集合体
为什么选择SpringCloud作为微服务架构 选型依据 1.整体解决方案和框架成熟度
2.社区热度
3.可维护性
4.学习曲线
主流IT公司用的微服务架构 阿里Dubbo/HSF
京东JSF
新浪微博Motan
当当网DubboX
SpringCloud入门概述 SpringCloud是什么 SpringCloud是分布式微服务架构下的一站式解决方案,是各个微服务架构落地技术的集合体,俗称微服务全家桶
SpringCloud和SpringBoot的关系 1.SpringBoot专注于快速、方便的开发单个微服务个体,SpringCloud关注全局的服务治理框架 ,它将SpringBoot开发的一个个单体微服务整合并管理起来,为各个微服务之间提供各种集成服务
2.SpringCloud可以离开SpringCloud独立使用开发项目,但是SpringCloud离不开SpringBoot,属于依赖关系
Rest微服务案例 microservicecloud父工程构建步骤 1.命名为microservicecloud,pom文件中packing类型为pom
<?xml version="1.0" encoding="UTF-8" ?> <project xmlns ="http://maven.apache.org/POM/4.0.0" xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation ="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" > <modelVersion > 4.0.0</modelVersion > <groupId > com.atguigu.springcloud</groupId > <artifactId > microservicecloud</artifactId > <version > 1.0-SNAPSHOT</version > <packaging > pom</packaging > <properties > <project.build.sourceEncoding > UTF-8</project.build.sourceEncoding > <maven.compiler.source > 1.8</maven.compiler.source > <maven.compiler.target > 1.8</maven.compiler.target > <junit.version > 4.12</junit.version > <log4j.version > 1.2.17</log4j.version > <lombok.version > 1.16.18</lombok.version > </properties > <dependencies > <dependency > <groupId > org.springframework.cloud</groupId > <artifactId > spring-cloud-dependencies</artifactId > <version > Dalston.SR1</version > <type > pom</type > <scope > import</scope > </dependency > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-dependencies</artifactId > <version > 1.5.9.RELEASE</version > <type > pom</type > <scope > import</scope > </dependency > <dependency > <groupId > mysql</groupId > <artifactId > mysql-connector-java</artifactId > <version > 5.0.4</version > </dependency > <dependency > <groupId > com.alibaba</groupId > <artifactId > druid</artifactId > <version > 1.2.8</version > </dependency > <dependency > <groupId > org.mybatis.spring.boot</groupId > <artifactId > mybatis-spring-boot-starter</artifactId > <version > 2.1.3</version > </dependency > <dependency > <groupId > ch.qos.logback</groupId > <artifactId > logback-core</artifactId > <version > 1.2.3</version > </dependency > <dependency > <groupId > junit</groupId > <artifactId > junit</artifactId > <version > ${junit.version}</version > <scope > test</scope > </dependency > <dependency > <groupId > log4j</groupId > <artifactId > log4j</artifactId > <version > ${log4j.version}</version > </dependency > </dependencies > </project >
microervicecloud-api公共子模块Module 1.新建microservicecloud-api模块 2.修改POM文件 <?xml version="1.0" encoding="UTF-8" ?> <project xmlns ="http://maven.apache.org/POM/4.0.0" xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation ="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" > <modelVersion > 4.0.0</modelVersion > <parent > <artifactId > microservicecloud</artifactId > <groupId > com.atguigu.springcloud</groupId > <version > 1.0-SNAPSHOT</version > </parent > <artifactId > microservicecloud-api</artifactId > <dependencies > <dependency > <groupId > org.projectlombok</groupId > <artifactId > lombok</artifactId > <version > 1.18.24</version > </dependency > <dependency > <groupId > org.apache.maven.plugins</groupId > <artifactId > maven-compiler-plugin</artifactId > <version > 3.8.1</version > </dependency > </dependencies > </project >
3.新建部门Entity且配合lombok使用
package com.atguigu.springcloud.entities;import jdk.jfr.DataAmount;import lombok.AllArgsConstructor;import lombok.Data;import lombok.NoArgsConstructor;import lombok.experimental.Accessors;import java.io.Serializable;@SuppressWarnings("serial") @Data @NoArgsConstructor @AllArgsConstructor @Accessors(chain = true) public class Dept implements Serializable { private Long deptno; private String dname; private String db_source; }
4.mvn clean install后给其他模块引用,达到通用目的。也即是需要用到部门实体的话,不用每个工程都定义一份,直接引用本模块即可 解决的问题:
1.attention:maven中作用域import只能在中使用
2.Fatal error compiling: 无效的标记(maven启动失败)
解决方案:JDK版本不一致/maven与lombok结合编译出现问题,maven版本较高,lombok jar包版本较低,因此编译lombok时无法编译。升级lombok的jar包版本或者降低maven版本。例如我的maven版本为3.5.2,之前报错的lombok版本为1.16.10,升级为1.18.10就不会报错了.
部门微服务提供者模块:microservicecloud-provider-dept-8001 1.新建microservicecloud-provider-dept-8001模块,修改POM文件 <?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 > microservicecloud</artifactId > <groupId > com.atguigu.springcloud</groupId > <version > 1.0-SNAPSHOT</version > </parent > <modelVersion > 4.0.0</modelVersion > <artifactId > microservicecloud-provider-dept-8001</artifactId > <dependencies > <dependency > <groupId > com.atguigu.springcloud</groupId > <artifactId > microservicecloud-api</artifactId > <version > ${project.version}</version > </dependency > <dependency > <groupId > junit</groupId > <artifactId > junit</artifactId > </dependency > <dependency > <groupId > mysql</groupId > <artifactId > mysql-connector-java</artifactId > </dependency > <dependency > <groupId > com.alibaba</groupId > <artifactId > druid</artifactId > </dependency > <dependency > <groupId > ch.qos.logback</groupId > <artifactId > logback-core</artifactId > </dependency > <dependency > <groupId > org.mybatis.spring.boot</groupId > <artifactId > mybatis-spring-boot-starter</artifactId > </dependency > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-jetty</artifactId > </dependency > <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 > </dependency > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-devtools</artifactId > </dependency > </dependencies > </project >
2.创建YML文件
server: port: 8001 mybatis: config-location: classpath:mybatis/mybatis.cfg.xml type-aliases-package: com.atguigu.springcloud.entities mapper-locations: - classpath:mybatis/mapper/**/*.xml spring: application: name: microservicecloud-dept datasource: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: org.gjt.mm.mysql.Driver url: jdbc:mysql://localhost:3306/cloudDB01 username: root password: root dbcp2: min-idle: 5 initial-size: 5 max-total: 5 max-wait-millis: 200
3.新建mybatis的配置文件 <?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 >
4.MySQL创建部门数据库脚本 DROP DATABASE IF EXISTS cloudDB01;CREATE DATABASE cloudDB01 CHARACTER SET UTF8;USE cloudDB01; CREATE TABLE dept( deptno BIGINT NOT NULL PRIMARY KEY AUTO_INCREMENT, dname VARCHAR (60 ), db_source VARCHAR (60 ) ); INSERT INTO dept(dname, db_source)VALUES ('开发部' , DATABASE());INSERT INTO dept(dname, db_source)VALUES ('人事部' , DATABASE());INSERT INTO dept(dname, db_source)VALUES ('财务部' , DATABASE());INSERT INTO dept(dname, db_source)VALUES ('市场部' , DATABASE());INSERT INTO dept(dname, db_source)VALUES ('运维部' , DATABASE());select * from dept
5.DeptDao部门接口 package com.atguigu.springcloud.dao;import com.atguigu.springcloud.entities.Dept;import org.apache.ibatis.annotations.Mapper;import java.util.List;@Mapper public interface DeptDao { public boolean addDept (Dept dept) ; public Dept findById (Long id) ; public List<Dept> findAll () ; }
6.创建mapper文件夹,再创键DeptMapper.xml映射文件 <?xml version="1.0" encoding="utf-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > <mapper namespace ="com.atguigu.springcloud.dao.DeptDao" > <select id ="findById" resultType ="Dept" parameterType ="Long" > select deptno,dname,db_source from dept where deptno = #{deptno}; </select > <select id ="findAll" resultType ="Dept" > select deptno,dname,db_source from dept; </select > <insert id ="addDept" parameterType ="Dept" > INSERT INTO dept(dname,db_source) VALUES(#{dname},DATABASE()); </insert > </mapper >
7.DeptService部门服务接口 package com.atguigu.springcloud.service;import com.atguigu.springcloud.entities.Dept;import java.util.List;public interface DeptService { public boolean add (Dept dept) ; public Dept get (Long id) ; public List<Dept> list () ; }
8.DeptServiceImpl部门服务接口实现类 package com.atguigu.springcloud.service.impl;import com.atguigu.springcloud.dao.DeptDao;import com.atguigu.springcloud.entities.Dept;import com.atguigu.springcloud.service.DeptService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import java.util.List;@Service public class DeptServiceImpl implements DeptService { @Autowired private DeptDao dao; @Override public boolean add (Dept dept) { return dao.addDept(dept); } @Override public Dept get (Long id) { return dao.findById(id); } @Override public List<Dept> list () { return dao.findAll() ; } }
9.DeptController部门微服务提供者REST package com.atguigu.springcloud.controller;import com.atguigu.springcloud.entities.Dept;import com.atguigu.springcloud.service.DeptService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.*;import java.util.List;@RestController public class DeptController { @Autowired private DeptService deptService; @RequestMapping(value = "/dept/add",method = RequestMethod.POST) public boolean add (@RequestBody Dept dept) { return deptService.add(dept); } @RequestMapping(value = "/dept/get/{id}",method = RequestMethod.GET) public Dept get (@PathVariable("id") Long id) { return deptService.get(id); } @RequestMapping(value = "/dept/list",method = RequestMethod.GET) public List<Dept> list () { return deptService.list(); } }
10.DeptProvider8001_App主启动类:DeptProvider8001_App package com.atguigu.springcloud;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication public class DeptProvider8001_App { public static void main (String[] args) { SpringApplication.run(DeptProvider8001_App.class,args); } }
11.测试
部门微服务消费者模块:microservicecloud-consumer-dept-80
1.新建新建microservicecloud-consumer-dept-80模块并修改pom文件 <?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 > microservicecloud</artifactId > <groupId > com.atguigu.springcloud</groupId > <version > 1.0-SNAPSHOT</version > </parent > <modelVersion > 4.0.0</modelVersion > <artifactId > microservicecloud-consumer-dept-80</artifactId > <description > 部门微服务消费者</description > <dependencies > <dependency > <groupId > com.atguigu.springcloud</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-devtools</artifactId > </dependency > </dependencies > </project >
2.创建并编写YML文件
3.com.atguigu.springcloud.cfgbeans包下ConfigBean的编写(类似spring里面的applicationContext.xml写入的注入Bean) package com.atguigu.springcloud.cfgbeans;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.web.client.RestTemplate;@Configuration public class ConfigBean { @Bean public RestTemplate getRestTemplate () { return new RestTemplate (); } }
package com.atguigu.springcloud.controller;import com.atguigu.springcloud.entities.Dept;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.PathVariable;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import org.springframework.web.client.RestTemplate;import java.util.List;@RestController public class DeptController_Consumer { private static final String REST_URL_PREFIX = "localhost:8001" ; @Autowired private RestTemplate restTemplate; @RequestMapping(value = "/consumer/dept/add") public boolean add (Dept dept) { return restTemplate.postForObject(REST_URL_PREFIX+"/dept/add" ,dept,Boolean.class); } @RequestMapping(value = "/consumer/dept/list") public List<Dept> list () { return restTemplate.getForObject(REST_URL_PREFIX+"/dept/list" ,List.class); } @RequestMapping(value = "/consumer/dept/get/{id}") public Dept get (@PathVariable("id") Long id) { return restTemplate.getForObject(REST_URL_PREFIX+"/dept/get/" +id,Dept.class); } }
什么是RestTemplate?
RestTemplate提供了多种便捷访问远程Http服务的方法, 是一种简单便捷的访问restful服务模板类,是Spring提供的用于访问Rest服务的客户端模板工具集 。使用使用restTemplate访问restful接口非常的简单粗暴无脑。(url, requestMap, ResponseBean.class)这三个参数分别代表 REST请求地址、请求参数、HTTP响应转换被转换成的对象类型。
5.DeptConsumer80_App主启动类 package com.atguigu.springcloud; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * @ClassName DeptConsumer80_APP * @Description TODO * @Author 百里诀 * @Date 2022/10/15 9:50 * @Version 1.0 */ @SpringBootApplication public class DeptConsumer80_APP { public static void main(String[] args) { SpringApplication.run(DeptConsumer80_APP.class,args); } }
6.测试 http://localhost/consumer/dept/list
http://localhost/consumer/dept/get/2
Eureka服务注册与发现 Eureka是什么? Eureka是什么 Eureka是Netflix的一个子模块,也是核心模块之一。Eureka是一个基于REST的服务,用于定位服务,以实现云端中间层服务发现和故障转移。**服务注册与发现**对于微服务架构来说是非常重要的,有了服务发现与注册,只需要使用服务的标识符,就可以访问到服务,而不需要修改服务调用的配置文件了。功能类似于dubbo的注册中心,比如Zookeeper。
Eureka的原理讲解 基本架构 Spring Cloud 封装了 Netflix 公司开发的 Eureka 模块来实现服务注册和发现(请对比Zookeeper)。 Eureka 采用了 C-S 的设计架构。Eureka Server 作为服务注册功能的服务器,它是服务注册中心。 而系统中的其他微服务,使用 Eureka 的客户端连接到 Eureka Server并维持心跳连接。这样系统的维护人员就可以通过 Eureka Server 来监控系统中各个微服务是否正常运行。
SpringCloud 的一些其他模块(比如Zuul)就可以通过 Eureka Server 来发现系统中的其他微服务,并执行相关的逻辑。请注意和Dubbo的架构对比
Eureka包含两个组件:Eureka Server和Eureka Client。Eureka Server提供服务注册服务各个节点启动后,会在Eureka Server中进行注册,这样Eureka Server中的服务注册表中将会存储所有可用服务节点的信息,服务节点的信息可以在界面中直观的看到 Eureka Client是一个Java客户端,用于简化Eureka Server的交互。
客户端同时也具备一个内置的、使用轮询(round-robin)负载算法的负载均衡器。在应用启动后,将会向Eureka Server发送心跳(默认周期为30秒)。如果Eureka Server在多个心跳周期内没有接收到某个节点的心跳,EurekaServer将会从服务注册表中把这个服务节点移除(默认90秒)
三大角色 Eureka Server 提供服务注册和发现
Service Provider服务提供方将自身服务注册到Eureka,从而使服务消费方能够找到
Service Consumer服务消费方从Eureka获取注册服务列表,从而能够消费服务
eureka服务注册中心模块:microservicecloud-eureka-7001 1.新建microservicecloud-eureka-7001模块,并修改POM文件 <?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 > microservicecloud</artifactId > <groupId > com.atguigu.springcloud</groupId > <version > 1.0-SNAPSHOT</version > </parent > <modelVersion > 4.0.0</modelVersion > <artifactId > microservicecloud-eureka-7001</artifactId > <dependencies > <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 > </dependencies > </project >
<dependencyManagement > <dependencies > <dependency > <groupId > org.springframework.cloud</groupId > <artifactId > spring-cloud-dependencies</artifactId > <version > 2021.0.0</version > <type > pom</type > <scope > import</scope > </dependency > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-dependencies</artifactId > <version > 2.6.3</version > <type > pom</type > <scope > import</scope > </dependency >
切记切记切记!!!!!!!!!!!!!!!!!!!!!!!!父工程里的springboot和cloud版本一定要匹配,否则就会出各种错,例如Eureka初始化不能
2.新建对应的YML文件 server: port: 7001 eureka: instance: hostname: localhost client: register-with-eureka: false fetch-registry: false service-url: defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
3.EurekaServer7001_App主启动类 package com.atguigu.springcloud;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;@SpringBootApplication @EnableEurekaServer public class EurekaServer7001_APP { public static void main (String[] args) { SpringApplication.run(EurekaServer7001_APP.class, args); } }
4.测试 http://localhost:7001/
结果页面No application available 没有服务被发现,因为没有注册服务进来当然不可能有服务被发现
将已有的部门微服务注册进eureka服务中心:microservicecloud-provider-dept-8001 1.修改microservicecloud-provider-dept-8001模块的POM文件 <?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 > microservicecloud</artifactId > <groupId > com.atguigu.springcloud</groupId > <version > 1.0-SNAPSHOT</version > </parent > <modelVersion > 4.0.0</modelVersion > <artifactId > microservicecloud-provider-dept-8001</artifactId > <dependencies > <dependency > <groupId > com.atguigu.springcloud</groupId > <artifactId > microservicecloud-api</artifactId > <version > ${project.version}</version > </dependency > <dependency > <groupId > junit</groupId > <artifactId > junit</artifactId > </dependency > <dependency > <groupId > mysql</groupId > <artifactId > mysql-connector-java</artifactId > </dependency > <dependency > <groupId > com.alibaba</groupId > <artifactId > druid</artifactId > </dependency > <dependency > <groupId > ch.qos.logback</groupId > <artifactId > logback-core</artifactId > </dependency > <dependency > <groupId > org.mybatis.spring.boot</groupId > <artifactId > mybatis-spring-boot-starter</artifactId > </dependency > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-jetty</artifactId > </dependency > <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 > </dependency > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-devtools</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-eureka</artifactId > <version > 1.4.5.RELEASE</version > </dependency > <dependency > <groupId > org.springframework.cloud</groupId > <artifactId > spring-cloud-starter-bootstrap</artifactId > <version > 3.0.2</version > </dependency > </dependencies > </project >
attention!!!!SpringCloud Config配置出现“No spring.config.import property has been defined“问题,即是在微服务provider侧注册进eureka时发生的问题,这样解决: 在SpringCloud 2020.* 版本把bootstrap禁用了,导致在读取文件的时候读取不到而报错,所以我们只要把bootstrap从新导入进来就会生效了。
<dependency > <groupId > org.springframework.cloud</groupId > <artifactId > spring-cloud-starter-bootstrap</artifactId > <version > 3.0.2</version > </dependency >
2.修改YML文件 server: port: 8001 mybatis: config-location: classpath:mybatis/mybatis.cfg.xml type-aliases-package: com.atguigu.springcloud.entities mapper-locations: - classpath:mybatis/mapper/**/*.xml spring: application: name: microservicecloud-dept datasource: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: org.gjt.mm.mysql.Driver url: jdbc:mysql://localhost:3306/cloudDB01 username: root password: root dbcp2: min-idle: 5 initial-size: 5 max-total: 5 max-wait-millis: 200 eureka: client: service-url: defaultZone: http://localhost:7001/eureka
3.DeptProvider8001_App主启动类 package com.atguigu.springcloud;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.netflix.eureka.EnableEurekaClient;@SpringBootApplication @EnableEurekaClient public class DeptProvider8001_App { public static void main (String[] args) { SpringApplication.run(DeptProvider8001_App.class,args); } }
4.测试
先要启动EurekaServer7001和8001
http://localhost:7001/
actuator与注册微服务信息完善 1.主机名称:服务名称修改 修改microservicecloud-provider-dept-8001模块中的YML文件
eureka: client: service-url: defaultZone: http://localhost:7001/eureka instance: instance-id: 20001223
2.访问信息有IP信息提示 现在问题:没有IP提示
解决方案:修改microservicecloud-provider-dept-8001模块中的YML文件
eureka: client: service-url: defaultZone: http://localhost:7001/eureka instance: instance-id: 20001223 prefer-ip-address: true
3.微服务info内容详细信息 当前问题:超链接点击服务报告ErrorPage
解决方案:
1.修改microservicecloud-provider-dept-8001模块中的POM文件
<dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-actuator</artifactId > </dependency > </dependencies >
2.总的父工程microservicecloud修改pom.xml添加构建build信息
<?xml version="1.0" encoding="UTF-8" ?> <project xmlns ="http://maven.apache.org/POM/4.0.0" xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation ="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" > <modelVersion > 4.0.0</modelVersion > <groupId > com.atguigu.springcloud</groupId > <artifactId > microservicecloud</artifactId > <version > 1.0-SNAPSHOT</version > <modules > <module > microservicecloud-api</module > <module > microservicecloud-provider-dept-8001</module > <module > microservicecloud-consumer-dept-80</module > <module > microservicecloud-eureka-7001</module > </modules > <packaging > pom</packaging > <properties > <project.build.sourceEncoding > UTF-8</project.build.sourceEncoding > <junit.version > 4.12</junit.version > <log4j.version > 1.2.17</log4j.version > <lombok.version > 1.18.24</lombok.version > </properties > <dependencyManagement > <dependencies > <dependency > <groupId > org.springframework.cloud</groupId > <artifactId > spring-cloud-dependencies</artifactId > <version > 2021.0.0</version > <type > pom</type > <scope > import</scope > </dependency > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-dependencies</artifactId > <version > 2.6.3</version > <type > pom</type > <scope > import</scope > </dependency > <dependency > <groupId > mysql</groupId > <artifactId > mysql-connector-java</artifactId > <version > 5.0.4</version > </dependency > <dependency > <groupId > com.alibaba</groupId > <artifactId > druid</artifactId > <version > 1.2.8</version > </dependency > <dependency > <groupId > org.mybatis.spring.boot</groupId > <artifactId > mybatis-spring-boot-starter</artifactId > <version > 2.1.3</version > </dependency > <dependency > <groupId > ch.qos.logback</groupId > <artifactId > logback-core</artifactId > <version > 1.2.3</version > </dependency > <dependency > <groupId > junit</groupId > <artifactId > junit</artifactId > <version > ${junit.version}</version > <scope > test</scope > </dependency > <dependency > <groupId > log4j</groupId > <artifactId > log4j</artifactId > <version > ${log4j.version}</version > </dependency > </dependencies > </dependencyManagement > <build > <finalName > microservicecloud</finalName > <resources > <resource > <directory > src/main/resources</directory > <filtering > true</filtering > </resource > </resources > <plugins > <plugin > <groupId > org.apache.maven.plugins</groupId > <artifactId > maven-resources-plugin</artifactId > <configuration > <delimiters > <delimit > $</delimit > </delimiters > </configuration > </plugin > </plugins > </build > </project >
3.修改microservicecloud-provider-dept-8001模块中的YML文件
server: port: 8001 mybatis: config-location: classpath:mybatis/mybatis.cfg.xml type-aliases-package: com.atguigu.springcloud.entities mapper-locations: - classpath:mybatis/mapper/**/*.xml spring: application: name: microservicecloud-dept datasource: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: org.gjt.mm.mysql.Driver url: jdbc:mysql://localhost:3306/cloudDB01 username: root password: root dbcp2: min-idle: 5 initial-size: 5 max-total: 5 max-wait-millis: 200 eureka: client: service-url: defaultZone: http://localhost:7001/eureka instance: instance-id: 20001223 prefer-ip-address: true info: app.name: atguigu-microservicecloud company.name: www.atguigu.com build.artifactId: $project.artifactId$ build.version: $project.version$
eureka自我保护
某时刻某一个微服务不可用了,eureka不会立刻清理,依旧会对该微服务的信息进行保存
在自我保护模式中,Eureka Server会保护服务注册表中的信息,不再注销任何服务实例。当它收到的心跳数重新恢复到阈值以上时,该Eureka Server节点就会自动退出自我保护模式。它的设计哲学就是宁可保留错误的服务注册信息,也不盲目注销任何可能健康的服务实例。一句话:好死不如赖活着
microservicecloud-provider-dept-8001模块:服务发现Discovery
1.对于注册进eureka里面的微服务,可以通过服务发现来获得该服务的信息 2.修改microservicecloud-provider-dept-8001工程的DeptController package com.atguigu.springcloud.controller;import com.atguigu.springcloud.entities.Dept;import com.atguigu.springcloud.service.DeptService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.cloud.client.ServiceInstance;import org.springframework.cloud.client.discovery.DiscoveryClient;import org.springframework.web.bind.annotation.*;import java.util.List;@RestController public class DeptController { @Autowired private DeptService deptService; @RequestMapping(value = "/dept/add",method = RequestMethod.POST) public boolean add (@RequestBody Dept dept) { return deptService.add(dept); } @RequestMapping(value = "/dept/get/{id}",method = RequestMethod.GET) public Dept get (@PathVariable("id") Long id) { return deptService.get(id); } @RequestMapping(value = "/dept/list",method = RequestMethod.GET) public List<Dept> list () { return deptService.list(); } @Autowired private DiscoveryClient client; @RequestMapping(value = "/dept/discovery",method = RequestMethod.GET) public Object discovery () { List<String> list = client.getServices(); System.out.println("*******" + list); List<ServiceInstance> srvList = client.getInstances("MICROSERVICECLOUD-DEPT" ); for (ServiceInstance element : srvList) { System.out.println(element.getServiceId()+"\t" +element.getHost()+"\t" +element.getPort()+"\t" +element.getUri()); } return this .client; } }
3.DeptProvider8001_App主启动类 package com.atguigu.springcloud;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.client.discovery.EnableDiscoveryClient;import org.springframework.cloud.netflix.eureka.EnableEurekaClient;@SpringBootApplication @EnableEurekaClient @EnableDiscoveryClient public class DeptProvider8001_App { public static void main (String[] args) { SpringApplication.run(DeptProvider8001_App.class,args); } }
4.自测
5.修改microservicecloud-consumer-dept-80工程的DeptController_Consumer package com.atguigu.springcloud.controller;import com.atguigu.springcloud.entities.Dept;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.PathVariable;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import org.springframework.web.client.RestTemplate;import java.util.List;@RestController public class DeptController_Consumer { private static final String REST_URL_PREFIX = "http://localhost:8001" ; @Autowired private RestTemplate restTemplate; @RequestMapping(value = "/consumer/dept/add") public boolean add (Dept dept) { return restTemplate.postForObject(REST_URL_PREFIX+"/dept/add" ,dept,Boolean.class); } @RequestMapping(value = "/consumer/dept/list") public List<Dept> list () { return restTemplate.getForObject(REST_URL_PREFIX+"/dept/list" ,List.class); } @RequestMapping(value = "/consumer/dept/get/{id}") public Dept get (@PathVariable("id") Long id) { return restTemplate.getForObject(REST_URL_PREFIX+"/dept/get/" +id,Dept.class); } @RequestMapping(value = "/consumer/dept/discovery") public Object discovery () { return restTemplate.getForObject(REST_URL_PREFIX+"/dept/discovery" ,Object.class); } }
集群配置 1.新建microservicecloud-eureka-7002模块以及microservicecloud-eureka-7003模块并编写POM文件 <?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 > microservicecloud</artifactId > <groupId > com.atguigu.springcloud</groupId > <version > 1.0-SNAPSHOT</version > </parent > <modelVersion > 4.0.0</modelVersion > <artifactId > microservicecloud-eureka-7002</artifactId > <dependencies > <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 > </dependencies > </project >
<?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 > microservicecloud</artifactId > <groupId > com.atguigu.springcloud</groupId > <version > 1.0-SNAPSHOT</version > </parent > <modelVersion > 4.0.0</modelVersion > <artifactId > microservicecloud-eureka-7003</artifactId > <dependencies > <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 > </dependencies > </project >
2.修改7002和7003的主启动类 package com.atguigu.springcloud;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;@SpringBootApplication @EnableEurekaServer public class EurekaServer7003_APP { public static void main (String[] args) { SpringApplication.run(EurekaServer7003_APP.class, args); } }
package com.atguigu.springcloud;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;@SpringBootApplication @EnableEurekaServer public class EurekaServer7002_APP { public static void main (String[] args) { SpringApplication.run(EurekaServer7002_APP.class, args); } }
3.修改映射配置 找到C:\Windows\System32\drivers\etc路径下的hosts文件
4.3台eureka服务器的yml文件配置 server: port: 7001 eureka: instance: hostname: eureka7001.com client: register-with-eureka: false fetch-registry: false service-url: defaultZone: http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
server: port: 7002 eureka: instance: hostname: eureka7002.com client: register-with-eureka: false fetch-registry: false service-url: defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7003.com:7003/eureka/
server: port: 7003 eureka: instance: hostname: eureka7003.com client: register-with-eureka: false fetch-registry: false service-url: defaultZone: http://eureka7002.com:7002/eureka/,http://eureka7001.com:7001/eureka/
5.微服务发布到上面3台eureka集群配置中:microservicecloud-provider-dept-8001 server: port: 8001 mybatis: config-location: classpath:mybatis/mybatis.cfg.xml type-aliases-package: com.atguigu.springcloud.entities mapper-locations: - classpath:mybatis/mapper/**/*.xml spring: application: name: microservicecloud-dept datasource: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: org.gjt.mm.mysql.Driver url: jdbc:mysql://localhost:3306/cloudDB01 username: root password: root dbcp2: min-idle: 5 initial-size: 5 max-total: 5 max-wait-millis: 200 eureka: client: service-url: defaultZone: instance: instance-id: 20001223 prefer-ip-address: true info: app.name: atguigu-microservicecloud company.name: www.atguigu.com build.artifactId: $project.artifactId$ build.version: $project.version$
作为服务注册中心,Eureka比Zookeeper好在哪里 RDBMS(mysql/oracle/sqlServer) ===>> ACID
NOSQL(redis/mongdb) ===>> CAP
1.什么是ACID A(Atomicity)原子性
C(Consistency)一致性
I(Isolation)独立性
D(Durability)持久性
2.CAP C(Consistency)强一致性
A(Availability)可用性
P(Partition tolerance)分区容错性
3.经典CAP图
4.Eureka比Zookeeper好在哪里 著名的CAP理论指出,一个分布式系统不可能同时满足C(一致性)、A(可用性)和P(分区容错性)。由于分区容错性P在是分布式系统中必须要保证的,所以我们只能在A和C之间进行权衡
Zookeeper保证的是CP
Eureka则是AP
因此,Eureka可以很好的应对因网络故障导致部分节点失去联系的情况,而不会像zookeeper那样使整个注册服务瘫痪
Ribbon负载均衡 Ribbon概述 1.Ribbon是什么 Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡 的工具。
简单的说,Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡算法,将Netflix的中间层服务连接在一起。Ribbon客户端组件提供一系列完善的配置项如连接超时,重试等。简单的说,就是在配置文件中列出Load Balancer(简称LB)后面所有的机器,Ribbon会自动的帮助你基于某种规则(如简单轮询,随机连接等)去连接这些机器 。我们也很容易使用Ribbon实现自定义的负载均衡算法。
2.Ribbon的作用 LB(负载均衡): 即负载均衡(Load Balance),在微服务或分布式集群中经常用的一种应用。负载均衡简单的说就是将用户的请求平摊的分配到多个服务上,从而达到系统的HA。常见的负载均衡有软件Nginx,LVS,硬件 F5等。相应的在中间件,例如:dubbo和SpringCloud中均给我们提供了负载均衡,SpringCloud的负载均衡算法可以自定义。
集中式LB: 集中式LB即在服务的消费方和提供方之间使用独立的LB设施(可以是硬件,如F5, 也可以是软件,如nginx), 由该设施负责把访问请求通过某种策略转发至服务的提供方
进程内LB: 进程内LB将LB逻辑集成到消费方,消费方从服务注册中心获知有哪些地址可用,然后自己再从这些地址中选择出一个合适的服务器。Ribbon就属于进程内LB,它只是一个类库,集成于消费方进程,消费方通过它来获取到服务提供方的地址。
Ribbon配置初步 1.修改microservicecloud-consumer-dept-80模块里的pom文件 <?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 > microservicecloud</artifactId > <groupId > com.atguigu.springcloud</groupId > <version > 1.0-SNAPSHOT</version > </parent > <modelVersion > 4.0.0</modelVersion > <artifactId > microservicecloud-consumer-dept-80</artifactId > <description > 部门微服务消费者</description > <dependencies > <dependency > <groupId > com.atguigu.springcloud</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-devtools</artifactId > </dependency > <dependency > <groupId > org.springframework.cloud</groupId > <artifactId > spring-cloud-starter-eureka</artifactId > <version > 1.4.5.RELEASE</version > </dependency > <dependency > <groupId > org.springframework.cloud</groupId > <artifactId > spring-cloud-starter-ribbon</artifactId > <version > 1.3.0.RELEASE</version > </dependency > <dependency > <groupId > org.springframework.cloud</groupId > <artifactId > spring-cloud-starter-config</artifactId > </dependency > <dependency > <groupId > org.springframework.cloud</groupId > <artifactId > spring-cloud-starter-bootstrap</artifactId > <version > 3.0.3</version > </dependency > </dependencies > </project >
2.修改application.yml 追加eureka的服务注册地址 server: port: 80 eureka: client: register-with-eureka: false service-url: defaultZone: http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/,http://eureka7001.com:7001/eureka/
3.对ConfigBean进行新注解@LoadBalanced 获得Rest时加入Ribbon的配置 package com.atguigu.springcloud.cfgbeans;import org.springframework.cloud.client.loadbalancer.LoadBalanced;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.web.client.RestTemplate;@Configuration public class ConfigBean { @Bean @LoadBalanced public RestTemplate getRestTemplate () { return new RestTemplate (); } }
4.主启动类DeptConsumer80_App添加@EnableEurekaClient package com.atguigu.springcloud;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.netflix.eureka.EnableEurekaClient;@SpringBootApplication @EnableEurekaClient public class DeptConsumer80_APP { public static void main (String[] args) { SpringApplication.run(DeptConsumer80_APP.class,args); } }
5.修改DeptController_Consumer客户端访问类 package com.atguigu.springcloud.controller;import com.atguigu.springcloud.entities.Dept;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.PathVariable;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import org.springframework.web.client.RestTemplate;import java.util.List;@RestController public class DeptController_Consumer { private static final String REST_URL_PREFIX = "http://MICROSERVICECLOUD-DEPT" ; @Autowired private RestTemplate restTemplate; @RequestMapping(value = "/consumer/dept/add") public boolean add (Dept dept) { return restTemplate.postForObject(REST_URL_PREFIX+"/dept/add" ,dept,Boolean.class); } @RequestMapping(value = "/consumer/dept/list") public List<Dept> list () { return restTemplate.getForObject(REST_URL_PREFIX+"/dept/list" ,List.class); } @RequestMapping(value = "/consumer/dept/get/{id}") public Dept get (@PathVariable("id") Long id) { return restTemplate.getForObject(REST_URL_PREFIX+"/dept/get/" +id,Dept.class); } @RequestMapping(value = "/consumer/dept/discovery") public Object discovery () { return restTemplate.getForObject(REST_URL_PREFIX+"/dept/discovery" ,Object.class); } }
6.先启动3个eureka集群后,再启动microservicecloud-provider-dept-8001并注册进eureka 7.启动microservicecloud-consumer-dept-80 8.测试 http://localhost/consumer/dept/get/1
http://localhost/consumer/dept/list
http://localhost/consumer/dept/add?dname=大数据部
9.小总结 Ribbon和Eureka整合后Consumer可以直接调用服务而不用再关心地址和端口号
Ribbon负载均衡
1.参考microservicecloud-provider-dept-8001模块,新建两份,分别命名为8002,8003,复用8001的pom文件
2.新建8002/8003数据库,各自微服务分别连各自的数据库 DROP DATABASE IF EXISTS cloudDB02;CREATE DATABASE cloudDB02 CHARACTER SET UTF8;USE cloudDB02; CREATE TABLE dept( deptno BIGINT NOT NULL PRIMARY KEY AUTO_INCREMENT, dname VARCHAR (60 ), db_source VARCHAR (60 ) ); INSERT INTO dept(dname, db_source)VALUES ('开发部' , DATABASE());INSERT INTO dept(dname, db_source)VALUES ('人事部' , DATABASE());INSERT INTO dept(dname, db_source)VALUES ('财务部' , DATABASE());INSERT INTO dept(dname, db_source)VALUES ('市场部' , DATABASE());INSERT INTO dept(dname, db_source)VALUES ('运维部' , DATABASE());
DROP DATABASE IF EXISTS cloudDB03;CREATE DATABASE cloudDB03 CHARACTER SET UTF8;USE cloudDB03; CREATE TABLE dept( deptno BIGINT NOT NULL PRIMARY KEY AUTO_INCREMENT, dname VARCHAR (60 ), db_source VARCHAR (60 ) ); INSERT INTO dept(dname, db_source)VALUES ('开发部' , DATABASE());INSERT INTO dept(dname, db_source)VALUES ('人事部' , DATABASE());INSERT INTO dept(dname, db_source)VALUES ('财务部' , DATABASE());INSERT INTO dept(dname, db_source)VALUES ('市场部' , DATABASE());INSERT INTO dept(dname, db_source)VALUES ('运维部' , DATABASE());
3.修改8002/8003各自YML server: port: 8002 mybatis: config-location: classpath:mybatis/mybatis.cfg.xml type-aliases-package: com.atguigu.springcloud.entities mapper-locations: - classpath:mybatis/mapper/**/*.xml spring: application: name: microservicecloud-dept datasource: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: org.gjt.mm.mysql.Driver url: jdbc:mysql://localhost:3306/cloudDB02 username: root password: root dbcp2: min-idle: 5 initial-size: 5 max-total: 5 max-wait-millis: 200 eureka: client: service-url: defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/ instance: instance-id: 20001223 prefer-ip-address: true info: app.name: atguigu-microservicecloud company.name: www.atguigu.com build.artifactId: $project.artifactId$ build.version: $project.version$
server: port: 8003 mybatis: config-location: classpath:mybatis/mybatis.cfg.xml type-aliases-package: com.atguigu.springcloud.entities mapper-locations: - classpath:mybatis/mapper/**/*.xml spring: application: name: microservicecloud-dept datasource: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: org.gjt.mm.mysql.Driver url: jdbc:mysql://localhost:3306/cloudDB03 username: root password: root dbcp2: min-idle: 5 initial-size: 5 max-total: 5 max-wait-millis: 200 eureka: client: service-url: defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/ instance: instance-id: 20001223 prefer-ip-address: true info: app.name: atguigu-microservicecloud company.name: www.atguigu.com build.artifactId: $project.artifactId$ build.version: $project.version$
3.1 修改对应的端口
3.2数据库链接
3.3对外暴露的统一的服务实例名
4.启动3个eureka集群配置区 5.启动3个Dept微服务启动并各自测试通过 http://localhost:8001/dept/list
http://localhost:8002/dept/list
http://localhost:8003/dept/list
5.启动microservicecloud-consumer-dept-80 6.客户端通过Ribbon完成负载均衡并访问上一步的Dept微服务 http://localhost/consumer/dept/list
注意观察看到返回的数据库名字,各不相同,负载均衡实现
7.总结:Ribbon其实就是一个软负载均衡的客户端组件,他可以和其他所需请求的客户端结合使用,和eureka结合只是其中的一个实例。 Ribbon核心组件IRule 注意:springcloud在2020.0.0之后,移除掉了netflix-ribbon 使用eureka-client中的loadbalancer,使用自定义负载均衡不使用IRule接口。官方文档上有写,可以写一个配置类,可以与启动类同级 IRule:根据特定算法中从服务列表中选取一个要访问的服务
Ribbon自定义
1.修改microservicecloud-consumer-dept-80模块 2.主启动类添加@RibbonClient package com.atguigu.springcloud;import com.atguigu.myrule.MySelfRule;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.netflix.eureka.EnableEurekaClient;import org.springframework.cloud.netflix.ribbon.RibbonClient;@SpringBootApplication @EnableEurekaClient @RibbonClient(name = "MICROSERVICECLOUD-DEPT",configuration = MySelfRule.class) public class DeptConsumer80_APP { public static void main (String[] args) { SpringApplication.run(DeptConsumer80_APP.class,args); } }
3.注意配置细节
1.新建package com.atuigu.myrule,新建自定义Robbin规则类
package com.atguigu.myrule;import com.netflix.loadbalancer.IRule;import com.netflix.loadbalancer.RandomRule;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;@Configuration public class MySelfRule { @Bean public IRule myRule () { return new RandomRule (); } }
2.测试
4.自定义规则深度解析
问题:依旧是轮询策略,但是加上新的需求,每个服务器要求被调用5次。也即是以前是每台机器一次,现在是每台机器5次
1.参考源码修改为我们需求要求的RandomRule_ZY.java
package com.atguigu.myrule;import com.netflix.client.config.IClientConfig;import com.netflix.loadbalancer.AbstractLoadBalancerRule;import com.netflix.loadbalancer.ILoadBalancer;import com.netflix.loadbalancer.RandomRule;import com.netflix.loadbalancer.Server;import java.util.List;import java.util.Random;public class RandomRule_ZY extends AbstractLoadBalancerRule { Random rand; private int total = 0 ; private int currentIndex = 0 ; @Override public void initWithNiwsConfig (IClientConfig iClientConfig) { } @Override public Server choose (Object key) { return choose(getLoadBalancer(), key); } public Server choose (ILoadBalancer lb, Object key) { if (lb == null ) { return null ; } 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(); if (serverCount == 0 ) { return null ; } if (total < 5 ) { server = upList.get(currentIndex); total++; } else { total = 0 ; currentIndex++; if (currentIndex >= upList.size()) { currentIndex = 0 ; } } if (server == null ) { Thread.yield(); continue ; } if (server.isAlive()) { return (server); } server = null ; Thread.yield(); } return server; } }
2.测试
SpringCloud Ribbon 解决java.lang.IllegalStateExcepti No instances available for MICROSERVICECLOUD-DEPT
Spring Cloud 2020版本以后,默认移除了对Netflix的依赖,其中就包括Ribbon ,官方默认推荐使用Spring Cloud Loadbalancer正式替换Ribbon,并成为了Spring Cloud负载均衡器的唯一实现。
依赖的变化
<dependency > <groupId > org.springframework.cloud</groupId > <artifactId > spring-cloud-starter-loadbalancer</artifactId > <version > 2.2.1.RELEASE</version >
由此可见,自定义ribbon负载均衡策略会与依赖,版本产生一定的冲突,使用的时候需要注意。按照本项目的版本自定义规则暂时无法使用
Feign负载均衡 什么是Feign? Feign是一个声明式WebService客户端。使用Feign能让编写Web Service客户端更加简单, 它的使用方法是定义一个接口,然后在上面添加注解,同时也支持JAX-RS标准的注解。Feign也支持可拔插式的编码器和解码器。Spring Cloud对Feign进行了封装,使其支持了Spring MVC标准注解和HttpMessageConverters。Feign可以与Eureka和Ribbon组合使用以支持负载均衡。
Feigin是一个声明式的Web服务客户端,使得编写Web服务客户端变得非常容易,只需要创建一个接口,然后在上面添加注解即可
Feign集成了Ribbon利用Ribbon维护了MicroServiceCloud-Dept的服务列表信息,并且通过轮询实现了客户端的负载均衡。而与Ribbon不同的是,通过feign只需要定义服务绑定接口且以声明式的方法,优雅而简单的实现了服务调用
Feign使用步骤 1.参考microservicecloud-consumer-dept-80模块新建microservicecloud-consumer-dept-feign模块,修改对应的pom文件,主要添加对fegin的支持,修改主启动类的名字 <?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 > microservicecloud</artifactId > <groupId > com.atguigu.springcloud</groupId > <version > 1.0-SNAPSHOT</version > </parent > <modelVersion > 4.0.0</modelVersion > <artifactId > microservicecloud-consumer-dept-feign</artifactId > <dependencies > <dependency > <groupId > com.atguigu.springcloud</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-devtools</artifactId > </dependency > <dependency > <groupId > org.springframework.cloud</groupId > <artifactId > spring-cloud-starter-eureka</artifactId > <version > 1.4.5.RELEASE</version > </dependency > <dependency > <groupId > org.springframework.cloud</groupId > <artifactId > spring-cloud-starter-config</artifactId > </dependency > <dependency > <groupId > org.springframework.cloud</groupId > <artifactId > spring-cloud-starter-bootstrap</artifactId > <version > 3.0.3</version > </dependency > <dependency > <groupId > org.springframework.cloud</groupId > <artifactId > spring-cloud-starter-loadbalancer</artifactId > <version > 2.2.1.RELEASE</version > </dependency > <dependency > <groupId > org.springframework.cloud</groupId > <artifactId > spring-cloud-starter-feign</artifactId > <version > 1.4.7.RELEASE</version > </dependency > </dependencies > </project >
package com.atguigu.springcloud;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.netflix.eureka.EnableEurekaClient;import org.springframework.cloud.openfeign.EnableFeignClients;import org.springframework.context.annotation.ComponentScan;@SpringBootApplication @EnableEurekaClient @EnableFeignClients(basePackages = {"com.atguigu.springcloud"}) public class DeptConsumer80_Feign_APP { public static void main (String[] args) { SpringApplication.run(DeptConsumer80_Feign_APP.class,args); } }
2.修改microservicecloud-api工程 2.1 修改对应的pom文件
<?xml version="1.0" encoding="UTF-8" ?> <project xmlns ="http://maven.apache.org/POM/4.0.0" xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation ="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" > <modelVersion > 4.0.0</modelVersion > <parent > <artifactId > microservicecloud</artifactId > <groupId > com.atguigu.springcloud</groupId > <version > 1.0-SNAPSHOT</version > </parent > <artifactId > microservicecloud-api</artifactId > <dependencies > <dependency > <groupId > org.projectlombok</groupId > <artifactId > lombok</artifactId > <version > 1.18.24</version > </dependency > <dependency > <groupId > org.apache.maven.plugins</groupId > <artifactId > maven-compiler-plugin</artifactId > <version > 3.8.1</version > </dependency > <dependency > <groupId > org.springframework.cloud</groupId > <artifactId > spring-cloud-starter-feign</artifactId > <version > 1.4.7.RELEASE</version > </dependency > </dependencies > </project >
2.2 新建DeptClientService接口并新增注解@FeignClient
package com.atguigu.springcloud.service;import com.atguigu.springcloud.entities.Dept;import org.springframework.cloud.openfeign.FeignClient;import org.springframework.stereotype.Service;import org.springframework.web.bind.annotation.PathVariable;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import java.util.List;@Service @FeignClient(value = "microservicecloud-dept") public interface DeptClientService { @RequestMapping(value = "/dept/get/{id}",method = RequestMethod.GET) public Dept get (@PathVariable("id") long id) ; @RequestMapping(value = "/dept/list",method = RequestMethod.GET) public List<Dept> list () ; @RequestMapping(value = "/dept/get/add",method = RequestMethod.POST) public boolean add (Dept dept) ; }
2.3 mvn clean
2.4 mvn install
3.microservicecloud-consumer-dept-feign工程修改Controller,添加上一步新建的DeptClientService接口 package com.atguigu.springcloud.controller;import com.atguigu.springcloud.entities.Dept;import com.atguigu.springcloud.service.DeptClientService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.PathVariable;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import org.springframework.web.client.RestTemplate;import java.util.List;@RestController public class DeptController_Consumer { @Autowired private DeptClientService service; @RequestMapping(value = "/consumer/dept/get/{id}") public Dept get (@PathVariable("id") Long id) { return this .service.get(id); } @RequestMapping(value = "/consumer/dept/list") public List<Dept> list () { return this .service.list(); } @RequestMapping(value = "/consumer/dept/add") public Object add (Dept dept) { return this .service.add(dept); } }
4.microservicecloud-consumer-dept-feign工程修改主启动类 package com.atguigu.springcloud;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.netflix.eureka.EnableEurekaClient;import org.springframework.cloud.openfeign.EnableFeignClients;@SpringBootApplication @EnableEurekaClient @EnableFeignClients(basePackages = {"com.atguigu.springcloud"}) public class DeptConsumer80_Feign_APP { public static void main (String[] args) { SpringApplication.run(DeptConsumer80_Feign_APP.class,args); } }
5.测试 5.1 启动3个eureka集群
5.2 启动3个部门微服务8001/8002/8003
5.3 启动Feign自己启动
5.4 http://localhost/consumer/dept/list
5.5 Feign自带负载均衡配置项
6.总结 Feign通过接口的方法调用Rest服务(之前是Ribbon+RestTemplate),该请求发送给Eureka服务器(http://MICROSERVICECLOUD-DEPT/dept/list),通过Feign直接找到服务接口,由于在进行服务调用的时候融合了Ribbon技术,所以也支持负载均衡作用。
Hystrix断路器 1.概述 1.1 分布式系统面临的问题 分布式系统面临的问题:复杂分布式体系结构中的应用程序有数十个依赖关系,每个依赖关系在某些时候将不可避免地失败。 服务雪崩多个微服务之间调用的时候,假设微服务A调用微服务B和微服务C,微服务B和微服务C又调用其它的微服务,这就是所谓的“扇出”。
**如果扇出的链路上某个微服务的调用响应时间过长或者不可用,对微服务A的调用就会占用越来越多的系统资源,进而引起系统崩溃,所谓的“雪崩效应”. **
对于高流量的应用来说,单一的后端依赖可能会导致所有服务器上的所有资源都在几秒钟内饱和。比失败更糟糕的是,这些应用程序还可能导致服务之间的延迟增加,备份队列,线程和其他系统资源紧张,导致整个系统发生更多的级联故障。这些都表示需要对故障和延迟进行隔离和管理,以便单个依赖关系的失败,不能取消整个应用程序或系统。
1.2 hystrix是什么? Hystrix是一个用于处理分布式系统的延迟和容错 的开源库,在分布式系统里,许多依赖不可避免的会调用失败,比如超时、异常等,Hystrix能够保证在一个依赖出问题的情况下,不会导致整体服务失败,避免级联故障,以提高分布式系统的弹性。
“断路器”本身是一种开关装置,当某个服务单元发生故障之后,通过断路器的故障监控(类似熔断保险丝),向调用方返回一个符合预期的、可处理的备选响应(FallBack),而不是长时间的等待或者抛出调用方无法处理的异常,这样就保证了服务调用方的线程不会被长时间、不必要地占用,从而避免了故障在分布式系统中的蔓延,乃至雪崩。
1.3 hystrix能干什么? 服务降级
服务熔断
服务限流
接近实时的监控
1.4 哪些情况会触发降级 程序运行异常
超时
服务熔断触发服务降级
线程池/信号量打满也会导致服务降级
2.服务熔断 2.1 服务熔断是什么? 服务熔断熔断机制是应对雪崩效应的一种微服务链路保护机制。当扇出链路的某个微服务不可用或者响应时间太长时,会进行服务的降级,进而熔断该节点微服务的调用,快速返回”错误”的响应信息。
当检测到该节点微服务调用响应正常后恢复调用链路。在SpringCloud框架里熔断机制通过Hystrix实现。Hystrix会监控微服务间调用的状况,当失败的调用到一定阈值,缺省是5秒内20次调用失败就会启动熔断机制。熔断机制的注解是@HystrixCommand。
2.2 参考microservicecloud-provider-dept-8001模块新建microservicecloud-provider-dept-hystrix-8001模块,修改pom文件 <?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 > microservicecloud</artifactId > <groupId > com.atguigu.springcloud</groupId > <version > 1.0-SNAPSHOT</version > </parent > <modelVersion > 4.0.0</modelVersion > <artifactId > microservicecloud-provider-dept-hystrix-8001</artifactId > <dependencies > <dependency > <groupId > org.springframework.cloud</groupId > <artifactId > spring-cloud-starter-netflix-hystrix</artifactId > <version > 2.1.0.RELEASE</version > </dependency > <dependency > <groupId > com.atguigu.springcloud</groupId > <artifactId > microservicecloud-api</artifactId > <version > ${project.version}</version > </dependency > <dependency > <groupId > junit</groupId > <artifactId > junit</artifactId > </dependency > <dependency > <groupId > mysql</groupId > <artifactId > mysql-connector-java</artifactId > </dependency > <dependency > <groupId > com.alibaba</groupId > <artifactId > druid</artifactId > </dependency > <dependency > <groupId > ch.qos.logback</groupId > <artifactId > logback-core</artifactId > </dependency > <dependency > <groupId > org.mybatis.spring.boot</groupId > <artifactId > mybatis-spring-boot-starter</artifactId > </dependency > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-jetty</artifactId > </dependency > <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 > </dependency > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-devtools</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-eureka</artifactId > <version > 1.4.5.RELEASE</version > </dependency > <dependency > <groupId > org.springframework.cloud</groupId > <artifactId > spring-cloud-starter-bootstrap</artifactId > <version > 3.0.2</version > </dependency > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-actuator</artifactId > </dependency > </dependencies > </project >
2.3 引入Hystrix熔断器启动项目失败 在pom.xml 中引入Hystrix后,启动项目失败,pom依赖如下:
报错信息如下: BeanDefinitionStoreException 和 FileNotFoundException,这是因ServerPropertiesAutoConfiguration 在springboot 2.x.x中已经废弃,所以找不到该文件。
解决方案是需要改换使用spring-cloud-starter-netflix-hystrix,如下:
2.4 修改YML文件 server: port: 8001 mybatis: config-location: classpath:mybatis/mybatis.cfg.xml type-aliases-package: com.atguigu.springcloud.entities mapper-locations: - classpath:mybatis/mapper/**/*.xml spring: application: name: microservicecloud-dept datasource: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: org.gjt.mm.mysql.Driver url: jdbc:mysql://localhost:3306/cloudDB01 username: root password: root dbcp2: min-idle: 5 initial-size: 5 max-total: 5 max-wait-millis: 200 eureka: client: service-url: defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/ instance: instance-id: microservicecloud-dept8001-hystrix prefer-ip-address: true info: app.name: atguigu-microservicecloud company.name: www.atguigu.com build.artifactId: $project.artifactId$ build.version: $project.version$
2.5 修改DeptController @HystrixCommand报异常后如何处理?
一旦调用服务方法失败并抛出了错误信息后,会自动调用@HystrixCommand标注好的fallbackMethod调用类中的指定方法
package com.atguigu.springcloud.controller;import com.atguigu.springcloud.entities.Dept;import com.atguigu.springcloud.service.DeptService;import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.cloud.client.ServiceInstance;import org.springframework.cloud.client.discovery.DiscoveryClient;import org.springframework.web.bind.annotation.*;import java.util.List;@RestController public class DeptController { @Autowired private DeptService service = null ; @RequestMapping(value = "/dept/get/{id}",method = RequestMethod.GET) @HystrixCommand(fallbackMethod = "processHystrix_Get") public Dept get (@PathVariable("id") Long id) { Dept dept = this .service.get(id); if (null ==dept) { throw new RuntimeException ("该ID:" + id + "没有对应的信息" ); } return dept; } public Dept processHystrix_Get (@PathVariable("id") Long id) { return new Dept ().setDeptno(id).setDname("该Id:" + id + "没有对应的信息,null-@HystrixComnand" ) .setDb_source("no this database in MySQl" ); } }
2.6 修改主启动类DeptProvider8001_Hystrix_App并添加新注解@EnableCircuitBreaker package com.atguigu.springcloud;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;import org.springframework.cloud.client.discovery.EnableDiscoveryClient;import org.springframework.cloud.netflix.eureka.EnableEurekaClient;@SpringBootApplication @EnableEurekaClient @EnableDiscoveryClient @EnableCircuitBreaker public class DeptProvider8001_Hystrix_App { public static void main (String[] args) { SpringApplication.run(DeptProvider8001_Hystrix_App.class,args); } }
2.7 测试 3个eureka先启动
主启动类DeptProvider8001_Hystrix_App
Consumer启动microservicecloud-consumer-dept-80
http://localhost/consumer/dept/get/112
3.服务降级 1.服务降级是什么? 整体资源快不够了,忍痛将某些服务先关掉,待渡过难关,再开启回来。
2.服务降级处理是在客户端实现完成的,与服务端没有关系 3.修改microservicecloud-api工程,根据已经有的DeptClientService接口新建一个实现了FallbackFactory接口的DeptClientServiceFallbackFactory 千万不要忘记在类上面新增@Component注解,大坑!!!
package com.atguigu.springcloud.service;import com.atguigu.springcloud.entities.Dept;import org.springframework.cloud.openfeign.FallbackFactory;import org.springframework.stereotype.Component;import java.util.List;@Component public class DeptClientServiceFallbackFactory implements FallbackFactory <DeptClientService> { @Override public DeptClientService create (Throwable cause) { return new DeptClientService () { @Override public Dept get (long id) { return new Dept ().setDeptno(id).setDname("该Id:" + id + "没有对应的信息,Consumer客户端提供的降级信息" ) .setDb_source("no this database in MySQl" ); } @Override public List<Dept> list () { return null ; } @Override public boolean add (Dept dept) { return false ; } }; } }
4.修改microservicecloud-api工程,DeptClientService接口在注解@FeignClient中添加fallbackFactory属性值 package com.atguigu.springcloud.service;import com.atguigu.springcloud.entities.Dept;import org.springframework.cloud.openfeign.FeignClient;import org.springframework.stereotype.Service;import org.springframework.web.bind.annotation.PathVariable;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import java.util.List;@Service @FeignClient(value = "microservicecloud-dept",fallbackFactory = DeptClientServiceFallbackFactory.class) public interface DeptClientService { @RequestMapping(value = "/dept/get/{id}",method = RequestMethod.GET) public Dept get (@PathVariable("id") long id) ; @RequestMapping(value = "/dept/list",method = RequestMethod.GET) public List<Dept> list () ; @RequestMapping(value = "/dept/get/add",method = RequestMethod.POST) public boolean add (Dept dept) ; }
5.microservicecloud-api工程 mvn clean
mvn install
6.microservicecloud-consumer-dept-feign工程修改YML 2020版的SpringCloud熔断器fallback失效的问题
将配置文件改成:feign.circuitbreaker.enabled=true
feign: circuitbreaker: enabled: true
7.3个eureka先启动 8.微服务microservicecloud-provider-dept-8001启动 9.microservicecloud-consumer-dept-feign启动 11.故意关闭微服务microservicecloud-provider-dept-8001 13.客户端自己调用提示
此时服务端provider已经down了,但是我们做了服务降级处理,让客户端在服务端不可用时也会获得提示信息而不会挂起耗死服务器
服务监控hystrixDashboard 1.概述 除了隔离依赖服务的调用以外,Hystrix还提供了准实时的调用监控(Hystrix Dashboard),Hystrix会持续地记录所有通过Hystrix发起的请求的执行信息,并以统计报表和图形的形式展示给用户,包括每秒执行多少请求多少成功,多少失败等。
Netflix通过hystrix-metrics-event-stream项目实现了对以上指标的监控。Spring Cloud也提供了Hystrix Dashboard的整合,对监控内容转化成可视化界面。
2.新建工程microservicecloud-consumer-hystrix-dashboard模块 3.修改POM文件 <?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 > microservicecloud</artifactId > <groupId > com.atguigu.springcloud</groupId > <version > 1.0-SNAPSHOT</version > </parent > <modelVersion > 4.0.0</modelVersion > <artifactId > microservicecloud-consumer-hystrix-dashboard</artifactId > <dependencies > <dependency > <groupId > org.springframework.cloud</groupId > <artifactId > spring-cloud-starter-netflix-hystrix</artifactId > <version > 2.2.5.RELEASE</version > </dependency > <dependency > <groupId > org.springframework.cloud</groupId > <artifactId > spring-cloud-starter-netflix-hystrix-dashboard</artifactId > <version > 2.2.5.RELEASE</version > </dependency > </dependencies > </project >
4.修改YML文件
5.主启动类改名+新注解@EnableHystrixDashboard package com.atguigu.springcloud;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;@SpringBootApplication @EnableHystrixDashboard public class DeptConsumer_DashBoard_App { public static void main (String[] args) { SpringApplication.run(DeptConsumer_DashBoard_App.class,args); } }
6.所有Provider微服务提供类(8001/8002/8003)都需要监控依赖配置 <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-actuator</artifactId > </dependency >
7.启动microservicecloud-consumer-hystrix-dashboard该微服务监控消费端 http://localhost:9001/hystrix
8.启动3个eureka集群 9.启动microservicecloud-provider-dept-hystrix-8001模块 http://localhost:8001/dept/get/1
http://localhost:8001/hystrix.stream
10.监控测试 多次刷新http://localhost:8001/dept/get/1,填写监控地址http://localhost:8001/hystrix.stream,监控结果
7色
1圈:实心圆:共有两种含义。它通过颜色的变化代表了实例的健康程度,它的健康度从绿色<黄色<橙色<红色递减。该实心圆除了颜色的变化之外,它的大小也会根据实例的请求流量发生变化,流量越大该实心圆就越大。所以通过该实心圆的展示,就可以在大量的实例中快速的发现故障实例和高压力实例。
1线:曲线:用来记录2分钟内流量的相对变化,可以通过它来观察到流量的上升和下降趋势。
3.解决:SpringCloud出现Unable to connect to Command Metric Stream.的异常 当输入URL并且点击Monitor Stream 按钮后界面出现:Unable to connect to Command Metric Stream.
解决方案:
1.被监视项目中使用如下配置: package hystrix.feign.consumer7.config; import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServlet;import org.springframework.boot.web.servlet.ServletRegistrationBean;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration; @Configuration public class JavaConfig { @Bean public ServletRegistrationBean getServlet () { HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet (); ServletRegistrationBean registrationBean = new ServletRegistrationBean (streamServlet); registrationBean.setLoadOnStartup(1 ); registrationBean.addUrlMappings("/actuator/hystrix.stream" ); registrationBean.setName("hystrix.stream" ); return registrationBean; } }
2.监视项目使用如下配置: hystrix: dashboard: proxy-stream-allow-list: "*"
zuul路由网关
zuul的概述 zuul是什么? Zuul包含了对请求的路由和过滤两个最主要的功能:其中路由功能负责将外部请求转发到具体的微服务实例上,是实现外部访问统一入口的基础而过滤器功能则负责对请求的处理过程进行干预,是实现请求校验、服务聚合等功能的基础.
Zuul和Eureka进行整合,将Zuul自身注册为Eureka服务治理下的应用,同时从Eureka中获得其他微服务的消息,也即以后的访问微服务都是通过Zuul跳转后获得。
注意:Zuul服务最终还是会注册进Eureka
提供=代理+路由+过滤三大功能
zuul能干什么? 路由
过滤
路由基本配置 1.新建Module模块microservicecloud-zuul-gateway-9527模块,并修改POM文件 <?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 > microservicecloud</artifactId > <groupId > com.atguigu.springcloud</groupId > <version > 1.0-SNAPSHOT</version > </parent > <modelVersion > 4.0.0</modelVersion > <artifactId > microservicecloud-zuul-gateway-9527</artifactId > <dependencies > <dependency > <groupId > org.springframework.cloud</groupId > <artifactId > spring-cloud-starter-netflix-zuul</artifactId > <version > 2.2.10.RELEASE</version > </dependency > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-devtools</artifactId > </dependency > <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 > </dependency > <dependency > <groupId > com.atguigu.springcloud</groupId > <artifactId > microservicecloud-api</artifactId > <version > ${project.version}</version > </dependency > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-jetty</artifactId > </dependency > <dependency > <groupId > org.springframework.cloud</groupId > <artifactId > spring-cloud-starter-netflix-hystrix</artifactId > <version > 2.1.0.RELEASE</version > </dependency > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-actuator</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-bootstrap</artifactId > </dependency > </dependencies > </project >
2.创建并编写YML文件,将host修改为myzuul.com server: port: 9527 spring: application: name: microservicecloud-zuul-gateway eureka: client: service-url: defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/ instance: instance-id: gateway-9527.com prefer-ip-address: true hostname: myzuul.com info: app.name: atguigu-microservicecloud company.name: www.atguigu.com build.artifactId: $project.artifactId$ build.version: $project.version$
3.主启动类,@EnableZuulProxy package com.atguigu.springcloud;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.netflix.zuul.EnableZuulProxy;@SpringBootApplication @EnableZuulProxy public class Zuul_9527_StartSpringCloudApp { public static void main (String[] args) { SpringApplication.run(Zuul_9527_StartSpringCloudApp.class,args); } }
4.启动 三个eureka集群
一个服务提供类microservicecloud-provider-dept-8001
一个路由
5.测试 不用路由
http://localhost:8001/dept/get/2
启用路由
http://myzuul.com:9527/microservicecloud-dept/dept/get/2
路由访问映射规则 1.代理名称修改YML文件 zuul: routes: mydept.serviceId: mycroservicecloud-dept mydept.path: /mydept/**
此时出现的问题:
路由访问OK,http://myzuul.com:9527/mydept/dept/get/1
原路径访问OK,http://myzuul.com:9527/microservicecloud-dept/dept/get/2
2.原真实服务名忽略 zuul: routes: mydept.serviceId: mycroservicecloud-dept mydept.path: /mydept/** ignored-services: mycroservicecloud-dept
单个具体,多个可以用”*”
3.设置统一公共前缀 zuul: routes: mydept.serviceId: mycroservicecloud-dept mydept.path: /mydept/** ignored-services: mycroservicecloud-dept prefix: /atguigu
http://myzuul.com:9527/atguigu/mydept/dept/get/1
SpringCloudConfig分布式配置中心 概述 1.分布式系统面临的配置问题 2.是什么?
SpringCloud Config为微服务架构中的微服务提供集中化的外部配置支持,配置服务器为各个不同微服务应用的所有环境提供了一个中心化的外部配置
3.怎么玩? SpringCloud Config分为服务端合客户端两部分
服务端也被称为分布式配置中心 ,它是一个独立的微服务应用。用来连接配置服务器并为客户端提供获取配置信息,加密/解密信息等访问端接口
客户端则是通过指定的配置中心来管理应用资源,以及与业务相关的配置内容,并在启动的时候从配置中心获取和加载配置信息。配置服务器默认采用git来存储配置信息,这样就有助于对环境配置进行版本管理,并且可以通过git客户端工具来方便的管理和访问配置内容。
4.能干嘛?
5.与GitHub整合配置 SpringConfig服务端配置 1.用自己的GitHub账号在GitHub上新建一个名为microservicecloud-config的新Repository
2.由上一步获得SSH协议的git地址 git@github.com :Starhunter-23/microservicecloud-config.git
3.本地硬盘目录上新建git仓库并clone 本地地址:D:\myspringcloud-git
git命令:git clone git@github.com :Starhunter-23/microservicecloud-config.git
4.在本地D:\myspringcloud-git\microservicecloud-config里面新建一个yml文件
yml内容:
spring: profiles: active: - dev --- spring: profiles: dev application: name: microservicecloud-config-atguigu-dev --- spring: profiles: test application: name: microservicecloud-config-atguigu-test
保存格式一定为UTF-8
5.将上一步的YML文件推送到github上 git add .
git commit -m “init yml”
git push origin master
6.新建Module模块microservicecloud-config-3344它即为Cloud的配置中心模块并编写POM文件
<?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 > microservicecloud</artifactId > <groupId > com.atguigu.springcloud</groupId > <version > 1.0-SNAPSHOT</version > </parent > <modelVersion > 4.0.0</modelVersion > <artifactId > microservicecloud-config-3344</artifactId > <dependencies > <dependency > <groupId > org.springframework.cloud</groupId > <artifactId > spring-cloud-config-server</artifactId > </dependency > <dependency > <groupId > org.springframework.cloud</groupId > <artifactId > spring-cloud-starter-bootstrap</artifactId > <version > 3.0.3</version > </dependency > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-actuator</artifactId > </dependency > <dependency > <groupId > org.springframework.cloud</groupId > <artifactId > spring-cloud-starter-eureka</artifactId > <version > 1.4.5.RELEASE</version > </dependency > <dependency > <groupId > org.springframework.cloud</groupId > <artifactId > spring-cloud-starter-config</artifactId > </dependency > <dependency > <groupId > org.springframework.cloud</groupId > <artifactId > spring-cloud-starter-netflix-hystrix</artifactId > <version > 2.1.0.RELEASE</version > </dependency > <dependency > <groupId > org.eclipse.jgit</groupId > <artifactId > org.eclipse.jgit</artifactId > <version > 6.1.0.202203080745-r</version > </dependency > </dependencies > </project >
7.YML文件 server: port: 3344 spring: application: name: microservicecloud-config cloud: config: server: git: uri: https://github.com/Starhunter-23/microservicecloud-config.git username: 2312460355 @qq.com password: HOPEhope00 search-paths: - springcloud-config label: main
8.主启动类Config_3344_StartSpringCloudApp package com.atguigu.springcloud;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.config.server.EnableConfigServer;@SpringBootApplication @EnableConfigServer public class Config_3344_StartSpringCloudApp { public static void main (String[] args) { SpringApplication.run(Config_3344_StartSpringCloudApp.class,args); } }
9.windows下修改hosts文件,增加映射
10.测试通过Config微服务是否可以从GitHub上获取配置内容
11.配置读取规则
12.SpringCloud Config通过GitHub获取配置信息 3.SpringCloud Config客户端配置与测试 1.在本地D:\myspringcloud-git\microservicecloud-config路径下新建文件microservicecloud-config-client.yml
2.microservicecloud-config-client.yml内容 profiles: active: - dev --- server: port:8201 spring: profiles: dev application: name: microservicecloud-config-client eureka: client: service-url: defaultZone: http://eureka-dev.com:7001/eureka/ --- server: port:8202 spring: profiles: test application: name: microservicecloud-config-client eureka: client: service-url: defaultZone: http://eureka-test.com:7001/eureka/
3.将上一步提交到GitHub中
4.新建microservicecloud-config-client-3355模块并修改POM文件
<?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 > microservicecloud</artifactId > <groupId > com.atguigu.springcloud</groupId > <version > 1.0-SNAPSHOT</version > </parent > <modelVersion > 4.0.0</modelVersion > <artifactId > microservicecloud-config-client-3355</artifactId > <dependencies > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-web</artifactId > </dependency > <dependency > <groupId > org.springframework.cloud</groupId > <artifactId > spring-cloud-starter-bootstrap</artifactId > <version > 3.0.3</version > </dependency > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-test</artifactId > </dependency > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-devtools</artifactId > </dependency > <dependency > <groupId > org.springframework.cloud</groupId > <artifactId > spring-cloud-starter-eureka</artifactId > <version > 1.4.5.RELEASE</version > </dependency > <dependency > <groupId > org.springframework.cloud</groupId > <artifactId > spring-cloud-starter-config</artifactId > </dependency > <dependency > <groupId > org.springframework.cloud</groupId > <artifactId > spring-cloud-starter-netflix-hystrix</artifactId > <version > 2.1.0.RELEASE</version > </dependency > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-actuator</artifactId > </dependency > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-jetty</artifactId > </dependency > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-configuration-processor</artifactId > </dependency > </dependencies > </project >
5.bootstrap.yml
spring: cloud: config: name: microservicecloud-config-client profile: dev label: master uri: http://config-3344.com:3344
6.application.yml spring: application: name: microservicecloud-config-client
7.windows下修改hosts文件,增加映射
8.新建rest类,验证是否能从GitHub上读取配置 package com.atguigu.springcloud.rest;import org.springframework.beans.factory.annotation.Value;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;@RestController public class ConfigClientRest { @Value("${spring.application.name}") private String applicationName; @Value("${eureka.client.service-url.defaultZone}") private String eurekaServers; @Value("${server.port}") private String port; @RequestMapping("/config") public String getConfig () { String str = "applicationName: " +applicationName+"\t eurekaServers:" +eurekaServers+"\t port:" +port; System.out.println("***********str: " +str); return "applicationName: " +applicationName+"\t eurekaServers:" +eurekaServers+"\t port: " +port; } }
9.主启动类ConfigClient_3355_StartSpringCloudApp package com.atguigu.springcloud;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.boot.context.properties.ConfigurationProperties;import org.springframework.cloud.client.discovery.EnableDiscoveryClient;@SpringBootApplication @EnableDiscoveryClient public class ConfigClient_3355_StartSpringCloudApp { public static void main (String[] args) { SpringApplication.run(ConfigClient_3355_StartSpringCloudApp.class,args); } }
10.测试 1.启动Config配置中心3344微服务并且自测 http://config-3344.com:3344/application-dev.yml
2.启动3355作为Client准备访问 暂时无法解决问题
Injection of auto wired dependencies failed; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder ‘eureka.client.service-url.defaultZone’ in value “${eureka.client.service-url.defaultZone}”
3.bootstrap.yml里面的profile值是什么,决定从github上读取什么
成功实现了客户端3355访问SpringCloud Config3344通过GitHub获取配置信息
仙之巅,傲世间,有我Magi就有天