软件准备
- IDE(idea/eclipse)
- maven 3.2+/gradle4+
- jdk1.8+
- 文本编辑器
构建父工程
- 新建mavne project
- packageing是pom格式
- 配置maven配置文件,g(groupid)a(artifactId)v(version)坐标,把后续子 模块用到的jar包提出,类似抽象父类
<groupId>com.microserver.myBlog</groupId>
<artifactId>myBlog</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>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.SR4</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.2.2.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.0.31</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.0</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>
<!--取自上面properties标签定义版本-->
<version>${log4j.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
构建公共子模块
- 配置pom:配置公共模块需要的jar包
- 创建公共实体类: 使用Lombok,序列化,链式风格访问
@Accessors(chain = true)
- 控制台中进入公共模块文件夹下,执行 mvn clean install进行装载,如果有依赖错误解决错误
构建提供者模块
- 新建模块
pom 引用公共api模块,需要的jar包 热部署插件
<dependency><!-- 调用自定义api模块 -->
<groupId>com.microserver.myBlog</groupId>
<artifactId>microservicecloud-api</artifactId>
<version>${project.version}</version>
</dependency>
yml文件
server:
port: 8001
mybatis:
config-location: classpath:mybatis/mybatis2.cfg.xml #mybatis 配置路径
type-aliases-package: com.microserver.myBlog.entity #所有entity别名类所在包
mapper-locations:
- classpath:mybatis/mapper/**/*.xml #mapper映射文件
spring:
application:
name: microservicecloud-blog
datasource:
type: com.alibaba.druid.pool.DruidDataSource #当前数据源操作类型
driver-class-name: org.gjt.mm.mysql.Driver #mysql驱动包
url: jdbc:mysql://localhost:3306/blog #url
username: root
password: root
dpcp2:
min-idle: 5 #数据库最小连接数
initial-size: 5 #初始化连接数
max-total: 5 #最大连接数
max-wait-millis: 200 #等待连接获取最大超时时间
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"><!--二级缓存 -->
</setting>
</settings>
</configuration>
mysql创建数据库表
blog接口
mapper.xml
service、controller层编写
主类
测试运行
构建消费者模块
pom
<properties>
<start-class>com.microservice.springcloud.ConsumerMain</start-class>
</properties>
<artifactId>microservice-consumer</artifactId>
<description>博客消费者</description>
<dependencies>
<dependency>
<groupId>com.microservice.springcloud</groupId>
<artifactId>microservice-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--修改后立即生效,热部署-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>springloaded</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>${start-class}</mainClass>
<layout>ZIP</layout>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
yml
server:
port: 80
添加组件
编写消费者模块的接口
eureka注册中心模块
pom
<parent>
<artifactId>blog</artifactId>
<groupId>com.microservice.springcloud</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>microservice-eureka</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
<!--修改后立即生效,热部署-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>springloaded</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
yml配置
server:
port: 7001
eureka:
instance:
hostname: localhost #eureka服务调的实例名称
client:
register-with-eureka: false #false表示不向注册中心注册自己
fetch-registry: false #false 表示我就是注册中心,职责是维护服务实例,不需要检索服务
service-url:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ #设置与eureka server交互的地址 查询服务和注册服务依赖这个地址
server:
#是否开启自我保护模式,默认为true。
enable-self-preservation: true
#续期时间,即扫描失效服务的间隔时间(缺省为60*1000ms)
eviction-interval-timer-in-ms: 10000
spring:
devtools:
livereload:
port: 35731
remote:
restart:
enabled: false
add-properties: true
主启动类
@SpringBootApplication
@EnableEurekaServer //eureka服务注释
public class EurekaMain {
public static final Logger logger = LoggerFactory.getLogger(EurekaMain.class);
public static void main(String[] args) {
SpringApplication.run(EurekaMain.class, args);
logger.info("*************************EurekaMain:启动成功******************************");
}
}
修改provider模块
pom新增
<!--将服务provider注册进eureka-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
application.yml新增
#服务注册的eureka地址
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka
主启动类添加注解
@EnableEurekaClient
主机映射名称修改
- 修改provider yml
eureka:
instance:
instance-id: microservice-provider #映射名称
主机ip信息提示
eureka:
instance:
instance-id: microservice-provider #映射名称
prefer-ip-address: true #访问路径可以显示ip地址
info内容构建
provider pom添加
<!--主管监控和信息配置-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
父工程添加build信息
<!--解析路径src/main/resources 下 以$符号括起来的数据-->
<build>
<finalName>${project.name}</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>
<delimiter>$</delimiter>
</delimiters>
</configuration>
</plugin>
</plugins>
</build>
修改provider工程yml
info:
app.name: blog-microsoftcloud
company.name: www.microsoftcloud.com
build.artifactId: $project.artifactId$
build.version: $project.version$
springcoud的自我保护机制(eureka模块)
eureka:
server:
#是否开启自我保护模式,默认为true。
enable-self-preservation: true
-
eureka服务发现
对于注册进eureka中的服务,可以通过服务发现获取服务信息添加获取服务信息接口
@Autowired
private DiscoveryClient discoveryClient;
@RequestMapping(value = "/discovery", method = RequestMethod.GET)
@ResponseBody
public Object discovery(){
List<String> list = discoveryClient.getServices();
System.out.println("******" + list);
List<ServiceInstance> srvList = discoveryClient.getInstances("MICROSERVICECLOUD-BLOG");
for (ServiceInstance element : srvList) {
System.out.println(element.getServiceId() + "\t" + element.getHost() + "\t" + element.getPort() + "\t" + element.getUri());
}
return this.discoveryClient;
}
provicer主启动类添加注释
@EnableDiscoveryClient//服务发现
消费端调用发现接口
//消费端调用服务发现
@RequestMapping(value = "/blog/discovery")
public Object discovery(){
return restTemplate.getForObject(RES_URL_PREFIX + "/blog/discovery", Object.class);
}
eureka集群配置
- 添加模块 microservice-eureka02和microservice-eureka03
- pom拷贝microservice-eureka模块的pom
- 添加主启动类microservice-eureka02的EurekaMain02和microservice-eureka03的EurekaMain03
- 域名映射 (win10环境文件路路径:C:\Windows\System32\drivers\etc\hosts)
127.0.0.1 eureka7001.com
127.0.0.1 eureka7002.com
127.0.0.1 eureka7003.com
- 模块 microservice-eureka01, microservice-eureka02和microservice-eureka03 yml文件
server:
port: 7001
eureka:
instance:
hostname: eureka7001.com #eureka服务调的实例名称
client:
register-with-eureka: false #false表示不向注册中心注册自己
fetch-registry: false #false 表示我就是注册中心,职责是维护服务实例,不需要检索服务
service-url:
defaultZone: http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
#defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ #设置与eureka server交互的地址 查询服务和注册服务依赖这个地址
server:
#是否开启自我保护模式,默认为true。
enable-self-preservation: true
#续期时间,即扫描失效服务的间隔时间(缺省为60*1000ms)
#eviction-interval-timer-in-ms: 10000
spring:
devtools:
livereload:
port: 35731
remote:
restart:
enabled: false
add-properties: true
server:
port: 7002
eureka:
instance:
hostname: eureka7002.com #eureka服务调的实例名称
client:
register-with-eureka: false #false表示不向注册中心注册自己
fetch-registry: false #false 表示我就是注册中心,职责是维护服务实例,不需要检索服务
service-url:
defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7003.com:7003/eureka/
#defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ #设置与eureka server交互的地址 查询服务和注册服务依赖这个地址
server:
#是否开启自我保护模式,默认为true。
enable-self-preservation: true
#续期时间,即扫描失效服务的间隔时间(缺省为60*1000ms)
#eviction-interval-timer-in-ms: 10000
spring:
devtools:
livereload:
port: 35732
remote:
restart:
enabled: false
add-properties: true
server:
port: 7003
eureka:
instance:
hostname: eureka7003.com #eureka服务调的实例名称
client:
register-with-eureka: false #false表示不向注册中心注册自己
fetch-registry: false #false 表示我就是注册中心,职责是维护服务实例,不需要检索服务
service-url:
defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/
#defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ #设置与eureka server交互的地址 查询服务和注册服务依赖这个地址
server:
#是否开启自我保护模式,默认为true。
enable-self-preservation: true
#续期时间,即扫描失效服务的间隔时间(缺省为60*1000ms)
#eviction-interval-timer-in-ms: 10000
spring:
devtools:
livereload:
port: 35733
remote:
restart:
enabled: false
add-properties: true
- 修改provider yml文件
eureka:
client:
service-url:
defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
#defaultZone: http://localhost:7001/eureka
引申学习:引入cloud新技术组件一般步骤
- 新增mavne坐标
- yml修改
- 在主启动类添加启动该技术组件的标签
//例如
@EnableEurekaServer
- 业务逻辑代码
eureka与zookeeper比较
- eureka遵守AP,zookeeper遵守CP
1)传统的ACID即关系型数据库事物的特点
原子性 独立性 一致性 持久性
2)nosql数据库 CAP
强一致性 可用性 分区容错性
分布式系统只能满足其中两个特性 其中分区容错是必有的
Ribbon 客户端的负载均衡
含义 麦当劳排队买汉堡,新来的排在人少的一队
ribbon配置
1)consumer模块 pom文件新增
<!--Ribbon相关 -->
<!--Ribbon需要和Eureka整合使用-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</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-ribbon</artifactId>
</dependency>
2)consumer模块 yml文件新增
eureka: #ribbon相关eureka配置
client:
register-with-eureka: false
service-url:
defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
3)consumer模块 restTemplate模型配置类ConfigBean添加注解
@Configuration
public class ConfigBean {
@Bean
//spring cloud Ribbon是基于Netfix Ribbon实现的一套客户端 负载均衡工具
@LoadBalanced //添加负在均衡注解
public RestTemplate getRestTemplate() {
return new RestTemplate();
}
}
4)consumer模块 主启动类添加注解
@EnableEurekaClient
5)consumer模块 controller层
//修改:
public static final String RES_URL_PREFIX = "http://localhost:8001";
//修改为:
public static final String RES_URL_PREFIX = "http://MICROSERVICECLOUD-BLOG";
-
测试地址:http://localhost/consumer/blog/list
-
Ribbon和Eureka整合可以直接调用服务而不用关心地址和端口
Ribbon的工作实现
- Ribbon的官方网址: https://github.com/Netflix/ribbon
1)Ribbon分两步
第一步选择EurekaServer,它优先选择在同一区域内负载较少 的server;
第二部根据用户指定策略,在从server取到的服务注册列表中 选择一个地址
2)添加模块microservice-provider02和microservice- provider03
- pom 文件与microservice-provider pom相同
- 拷贝模块microservice-provider对应代码 主启动类修改名称
添加对应的数据库clouddb02和clouddb03
– 举例sql脚本
DROP DATABASE IF EXISTS clouddb03;
CREATE DATABASE clouddb03 CHARACTER SET UTF8;
USE clouddb03;
CREATE TABLE blog (
id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID',
title VARCHAR(200) NOT NULL,
content TEXT ,
views INT DEFAULT 0,
blog_type VARCHAR(50),
update_time DATETIME,
create_time DATETIME,
db_source VARCHAR(5`clouddb02`0)
);
INSERT INTO blog(title, content, views, blog_type, update_time, create_time, db_source)
VALUES('my first blog','my first blog',0,'JavaScript',NOW(),NOW(), DATABASE())
-
拷贝模块microservice-provider对应配置文件mybatis文件夹和yml文件(端口/数据库名/livereload/instance-id(映射名))
-
测试地址
http://localhost:8001/blog/getBlogs
http://localhost:8002/blog/getBlogs
http://localhost:8003/blog/getBlogs
http://localhost/consumer/blog/list #不断刷新该地址 查看访问服务变化
Ribbon核心组件IRule
-
根据特定算法从服务列表中选取一个要访问的服务
-
consumer模块 restTemplate模型配置类ConfigBean添加新访问顺序方法
@Bean
public IRule myRule(){
// return new RoundRobinRule();//默认轮询算法
// return new RandomRule();//用随机算法替换默认轮询算法
return new RetryRule();//用重试算法替换默认轮询算法,默认轮询算法,若多次重试失败回自动跳过失败服务
}
Ribbon自定义算法
- consumer模块主启动类添加注解
//在启动该微服务的时候就能加载我们自定义的Ribbon配置类
@RibbonClient(name = "MICROSERVICECLOUD-BLOG", configuration = MySelfRule.class)
- 自定义配置类
自定义配置类不能放在@ComponentScan所扫描的包或包下,否则配置类被所有Ribbon客户端共享,即达不到特殊化定制的目的,主启动类@SpringbootApplication注解包含@ComponentScan,所以不能和主启动类在同一包下
1.新建包
2.配置类
@Configuration
public class MySelfRule {
@Bean
public IRule myRule(){
return new RandomRule();//编写自己的自定义算法
}
}
Feign负载均衡
- Feign是一个声明式的Web服务客户端,使编写web服务客户端更容易 只要创建一个接口,然后添加注解即可
- 添加Feign模块microservice-consumer-feign
- 拷贝consumer模块代码和配置,pom文件到该模块,修改主启动类名称 去除Ribbon的相关注解
- 添加pom相关依赖
<!--Feign相关-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
- 修改microservice-api模块,pom文件添加feign相关依赖
- 修改microservice-api模块,新建BlogClientService接口,新增注解
@FeignClient(value = "MICROSERVICECLOUD-BLOG")
- api模块 执行mvn clean install 命令
- Feign模块controller编写调用方法
- Feign模块主启动类添加注解
@EnableFeignClients(basePackages = {"com.microservice.springcloud"})
- 测试 ,不启用consumer模块,测试地址: http://localhost/consumer/blog/list
Hystrix断路器
-
复杂分布式系统结构中的应用程序有数十个依赖关系,每个依赖关系在某些时候将不可避免的失败
访问失败后,向调用方返回一个符合预期的、可处理的备选响应,而不是长时间等待或抛出调用方法无法处理的异常 -
借鉴provider模块创建Hystrix模块microservice-hystrix,拷贝provider代码,yml,配置文件
pom文件添加
<!--Hystrix相关-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
yml修改属性
instance-id: microservice-hystrix #映射名称
修改controller
@RequestMapping(value = "/getBlogById/{id}", method = RequestMethod.GET)
@HystrixCommand(fallbackMethod = "processHystrix_Get")
public Blog getBlogById(@PathVariable("id") String id) {
Blog blog = blogService.getBlogById(id);
if(null == blog){
throw new RuntimeException("该ID:" + id + "没有对应信息");
}
return blog;
}
public Blog processHystrix_Get(@PathVariable("id") String id) {
return new Blog().setId(id).setTitle("该ID:" + id + "没有对应信息,null--@HystrixCommand")
.setDbSource("no this database in MySQL");
}
- Hystrix模块主启动类添加注解
@EnableCircuitBreaker//hystrix熔断机制
- 测试
启动3个eureka服务,启动hystrix服务
测试地址: http://eureka7001.com:7001/
http://localhost:8001/blog/getBlogById/1 ID存在
http://localhost:8001/blog/getBlogById/55 ID不存在
Hystrix 服务降级
即整体资源不够用了,忍痛将某些服务关掉,度过难关,再开启。
- api模块添加Hystrix的service处理方法BlogClientServiceFallbackFactory
- api模块类BlogClientService中添加修改注解
@FeignClient(value = "MICROSERVICECLOUD-BLOG")
//修改为
@FeignClient(value = "MICROSERVICECLOUD-BLOG", fallbackFactory = BlogClientServiceFallbackFactory.class)
- api模块 执行 mvn clean install
- microservice-consumer-feign模块 yml文件添加
feign:
hystrix:
enabled: true
- 测试
启动服务 eureka三个服务,provider feign服务
访问:http://localhost/consumer/blog/getBlogById/1
关闭服务provider
访问:http://localhost/consumer/blog/getBlogById/3
服务监控HystrixDashboard
- 添加模块microservice-consumer-hystrix-dashboard
pom文件 拷贝consumer模块依赖,添加依赖
<!--Hystrix和Hystrix-dashboard-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
</dependency>
yml文件
server:
port: 9001
- 添加主启动类和对应注释
@EnableHystrixDashboard
确认各provider服务存在依赖
<!--主管监控和信息配置-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
- 启动hystrix-dashboard服务
访问地址: http://localhost:9001/hystrix
启动服务microservice-hystrix和microservice-consumer-hystrix-dashboard
访问地址: http://localhost:8001/hystrix.stream
图形变化界面
Zuul路由网关
Zuul包含路由和过滤功能,zuul注册进Eureka
- 新建模块microservice-zuul-gateway
pom文件常用依赖,并添加
<!--Zuul路由相关-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zuul</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
yml文件
server:
port: 9527
eureka:
instance:
instance-id: myzuul.com #映射名称
prefer-ip-address: true #访问路径可以显示ip地址
client:
service-url:
defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
#defaultZone: http://localhost:7001/eureka
info:
app.name: blog-microsoftcloud
company.name: www.microsoftcloud.com
build.artifactId: $project.artifactId$
build.version: $project.version$
spring:
application:
name: microservice-zuul-gateway
- 添加主启动类Zuul_9527_Main和注解
@EnableZuulProxy
修改hosts文件,添加
127.0.0.1 myzuul.com
- 测试 启动3个eureka \provider\gateway
访问地址: http://myzuul.com:9527/microservicecloud-blog/blog/getBlogById/1
Zuul路由的访问映射规则
yml文件,添加
zuul:
routes:
myBlog.serviceId: microservicecloud-blog
myBlog.path: /myBlog/**
- 测试
访问地址: http://myzuul.com:9527/myBlog/blog/getBlogById/1 - 屏蔽地址: http://myzuul.com:9527/microservicecloud-blog/blog/getBlogById/1
修改yml文件
zuul:
routes:
myBlog.serviceId: microservicecloud-blog
myBlog.path: /myBlog/**
#ignored-services: “*” #忽略多个服务
zuul:
routes:
myBlog.serviceId: microservicecloud-blog
myBlog.path: /myBlog/**
ignored-services: "*" #忽略多个微服务
#ignored-services: microservicecloud-blog #新增 忽略单个服务
prefix: /dev #服务前加前缀
- 访问地址: http://myzuul.com:9527/dev/myBlog/blog/getBlogById/2
SpringCloud Config分布式配置中心
- 作用:集中管理所有微服务的外部配置,分为服务端(获取配置信息)和客户端
- 远程仓库github创建git仓库microservice-config.git
- 克隆到本地,且在文件夹下创建文件application.yml,此文件要保存为utf-8编码
spring:
profiles:
active:
- dev
---
spring:
profiles: dev #开发环境
application:
name: microservice-cofig-myblog-dev
---
spring:
profiles: test #测试环境
application:
name: microservice-cofig-myblog-test
#请保存为UTF-8格式
- 把application.yml文件提交,推送到git仓库
- 新建模块microservice-config-server
pom文件
<!--springcloud-config相关-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
yml文件
server:
port: 3344
spring:
application:
name: microservice-config-server
cloud:
config:
server:
git:
uri: git@192.168.242.129:/home/gitrepo/microservice-config.git #git远程仓库名称
- 添加主启动类,并添加注释
@EnableConfigServer
修改hosts文件
127.0.0.1 config-3344.com
-
测试地址:
http://config-3344.com:3344/application-dev.ym
http://config-3344.com:3344/application-test.yml
http://config-3344.com:3344/application-abcd.yml -
在git文件夹下创建yml文件microservicecloud-config-client
spring:
profiles:
active:
- dev
---
server:
port: 8201
spring:
profiles: dev #开发环境
application:
name: microservice-cofig-client-myblog-dev
eureka:
client:
service-url:
defaultZone: http://eureka-dev.com:7001/eureka/
---
server:
port: 8202
spring:
profiles: test #测试环境
application:
name: microservice-cofig-client-myblog-test
eureka:
client:
service-url:
defaultZone: http://eureka-test.com:7001/eureka/
#请保存为UTF-8格式
- yml文件提交,推送到github
- 创建springcloud config 客户端模块
pom文件,添加
<!--springcloud-config-client相关-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config</artifactId>
</dependency>
- 添加bootstrap.yml文件和application.yml(application.yml 用户级的资源配置项;bootstrap.yml是系统级的,优先级最高, 从外部加载配置并解析配置)
server:
port: 3355
spring:
cloud:
config:
name: microservice-config-client
profile: dev
label: master
uri: http://config-3344.com:3344 #本微服务启动后先去找3344服务,通过SpringCloudConfig获取Github的服务地址
application.yml
spring:
application:
name: microservice-config-client
- hosts文件添加
127.0.0.1 client-config.com
- 获取3344服务配置信息类
@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 str;
}
- 添加主启动类
- 测试 地址:
http://client-config.com:8201/config
修改bootstrap.yml 中profile: dev 改为 profile: test
地址: http://client-config.com:8202/config
SpringCloud Config统一配置微服务
- 文件中添加文件microservice-config-eureka-client.yml和microservice-config-blog-client.yml
- 创建模块microservice-config-eureka-client
- 拷贝eureka模块pom文件中依赖到microservice-config-eureka-client模块pom
bootstrap.yml文件
spring:
cloud:
config:
name: microservice-config-eureka-client #github上的配置文件名称,没有yml文件后缀
profile: dev
label: master
uri: http://config-3344.com:3344 #本微服务启动后先去找3344服务,通过SpringCloudConfig获取Github的服务地址
application.yml文件
spring:
application:
name: microservice-config-eureka-client
-
测试
启动服务microservice-config-server
地址: http://config-3344.com:3344/application-dev.yml
启动服务microservice-config-eureka-client
地址: http://eureka7001.com:7001/ -
添加模块microservice-config-blog-client
pom文件拷贝provider 模块pom文件
bootstrap.yml
spring:
cloud:
config:
name: microservice-config-blog-client #github上的配置文件名称,没有yml文件后缀
profile: dev
label: master
uri: http://config-3344.com:3344 #本微服务启动后先去找3344服务,通过SpringCloudConfig获取Github的服务地址
application.yml
spring:
application:
name: microservice-config-blog-client
- 拷贝provider模块中的mybatis文件夹到microservice-config-blog-client
- 测试
启动服务microservice-config-server、microservice-config-eureka-client和microservice-config-blog-client
地址: http://localhost:8001/blog/getBlogs
修改bootstrap.yml 中profile: dev 改为 profile: test
地址: http://localhost:8001/blog/getBlogs
github上文件:
https://github.com/xiaoxiongxiong/microservice-config.git
项目代码:https://github.com/xiaoxiongxiong/springcloud.git
ssh :git@github.com:xiaoxiongxiong/springcloud.git
待更新 延申启动多服务需要写脚本
规范:约定》配置》编码
遇到异常:
1.无法引入api模块问题
//没有执行 mvn clean instal 命令
2.java.lang.IllegalStateException: Restarter has not been initialized
//因为devtools jar包依赖版本问题
3.org.apache.ibatis.binding.BindingException: Invalid bound statement (not found)
//mapper.xml内的namespace写错
4.com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class com.microservice.springcloud.entity.Blog and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: java.util.ArrayList[0])
//实体类没有实现Serializable implements Serializable
5.The error occurred while handling results ### SQL: select * from blog ### Cause: java.lang.UnsupportedOperationException
//
6.Could not find result map 'com.microservice.springcloud.entity.Blog' referenced from
//resultMap改为resultType
7.mybatisMapper.xml jdbcType = int 改为 jdbcType = INTEGER
8.如果表单删除数据
public Map<String, Object> deleteBlog(@RequestParam("id") String id){...
如果参数未json数据:
public Map<String, Object> deleteBlog(@RequestBody Map<String, Object> map){...
9.Could not autowire. No beans of 'RestTemplate' type found. less... (Ctrl+F1)
Inspection info:Checks autowiring problems in a bean class.
原因:provider模块的controller层与consumer模块的contrller层再同一包下,类名相同导致,修改类名错误消失
10.Error:(27, 60) java: 无法访问org.springframework.core.NestedRuntimeException
找不到org.springframework.core.NestedRuntimeException的类文件
原因:没有引用spring-core和spring-context jar包
11.java.lang.ClassNotFoundException: org.springframework.core.KotlinDetector
更改spring-core版本为5.0.1以上即可
12.org.springframework.core.KotlinDetector.isKotlinReflectPresent()
pom.xml中引入了spring-boot-starter-web ,同时pom.xml也引入了spring-core,spring-beans,这里去掉spring-core,spring-beans即可
12.maven窗口 模块为灰色
解决办法:
Preferences -> build -> maven -> ignore files,找到对应的maven模块,取消勾选。
jar包删除重新加载
13.java.lang.NoSuchMethodError: org.yaml.snakeyaml.nodes.ScalarNode.getScalarStyle()Lorg/yaml/snakeyaml/DumperOptions$ScalarStyle;
jar包依赖 环境问题
解决方法:确认模块jdk选择是否正确
参考资料:
阿里云大学
springcloud官网