微服务
微服务技术栈
在国内最知名的微服务技术框架就是SpringCloud和阿里巴巴的Dubbo。
微服务知识层次
微服务特征
微服务是一种经过良好架构设计的分布式架构方案,微服务架构特征:
- 单一职责:微服务拆分粒度更小,每一个服务都对应唯一的业务能力,做到单一职责,避免重复业务开发
- 面向服务:微服务对外暴露业务接口
- 自治:团队独立、技术独立、数据独立、部署独立
- 隔离性强:服务调用做好隔离、容错、降级,避免出现级联问题
微服务技术对比
SpringCloudAlibaba兼容前两种框架技术,通常我们使用SpringCloudAlibaba
SpringCloud
- SpringCloud是目前国内使用最广泛的微服务框架。官网地址:https://spring.io/projects/spring-cloud。
- SpringCloud集成了各种微服务功能组件,并基于SpringBoot实现了这些组件的自动装配,从而提供了良好的开箱即用体验:
SpringBoot与SpringCloud的兼容问题
服务调用关系
- 服务提供者:暴露接口给其它微服务调用
- 服务消费者:调用其它微服务提供的接口
- 一个服务可以同时是服务提供者和服务消费者
Eureka注册中心
Eureka注册中心的作用
- 消费者该如何获取服务提供者具体信息?
- 服务提供者启动时向eureka注册自己的信息
- eureka保存这些信息
- 消费者根据服务名称向eureka拉取提供者信息
- 如果有多个服务提供者,消费者该如何选择?
- 服务消费者利用负载均衡算法,从服务列表中挑选一个
- 消费者如何感知服务提供者健康状态?
- 服务提供者会每隔30秒向EurekaServer发送心跳请求,报告健康状态
- eureka会更新记录服务列表信息,心跳不正常会被剔除
- 消费者就可以拉取到最新的信息
Eureka的组成部分
在Eureka架构中,微服务角色有两类:
- EurekaServer:服务端,注册中心
- 记录服务信息
- 心跳监控
- EurekaClient:客户端
- Provider:服务提供者
- 注册自己的信息到EurekaServer
- 每隔30秒向EurekaServer发送心跳
- consumer:服务消费者
- 根据服务名称从EurekaServer拉取服务列表
- 基于服务列表做负载均衡,选中一个微服务后发起远程调用
- Provider:服务提供者
代码整合
父工程jar包统一版本控制
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.9.RELEASE</version> <!--不要轻易改变他的版本,因为他跟Spring-cloud版本有兼容问题-->
<relativePath/>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-cloud.version>Hoxton.SR10</spring-cloud.version>
<mysql.version>8.0.16</mysql.version>
<mybatis.version>2.1.1</mybatis.version>
</properties>
<!--jar包版本管理-->
<dependencyManagement>
<dependencies>
<!-- springCloud -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- mysql驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<!--mybatis-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>${mybatis.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
eureka注册中心
-
依赖:
<dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> </dependencies>
-
配置文件
server.port=10086 #服务注册需要的信息(注意eureka本身也是需要注册的,所以他也需要配置下面的注册信息) #eureka服务名称(便于注册到eureka注册中心) spring.application.name=eurekaserver #需要注册到eureka服务集群的地址(eureka集群地址,多个用逗号隔开,除了ip和端口是自己配置的,其他是死的) eureka.client.service-url.defaultZone=http://127.0.0.1:10086/eureka
-
启动类
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; @EnableEurekaServer //开启eureka注册服务 @SpringBootApplication public class App { public static void main(String[] args) { SpringApplication.run(App.class,args); } }
eureka客户端服务
-
依赖:
<dependencies> <!--SpringBootWeb服务--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--eureka客户端依赖---> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> </dependencies> <build> <plugins> <!--SpringBoot打包插件--> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
-
配置文件
server.port=8082 server.servlet.context-path=/orderService #服务注册需要的信息 #eureka客户端的服务名称 spring.application.name=orderservice #需要注册到eureka服务集群的地址 eureka.client.service-url.defaultZone=http://127.0.0.1:10086/eureka
-
启动类
import com.netflix.loadbalancer.IRule; import com.netflix.loadbalancer.RandomRule; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.context.annotation.Bean; import org.springframework.web.client.RestTemplate; @SpringBootApplication public class App { public static void main(String[] args) { SpringApplication.run(App.class,args); } @Bean public RestTemplate restTemplate(){ return new RestTemplate(); } }
-
访问demo
import cn.wfw.xuhx.util.Result; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate; @RestController @CrossOrigin(origins = "*",maxAge = 3600) @RequestMapping("/order") public class OrderController { @Autowired private RestTemplate restTemplate; @RequestMapping(value = "/queryUser" ,produces = "application/json;charset=utf-8",method = RequestMethod.GET) public Result queryUser(){ //注意:通过eureka注册中心去访问另外一个服务器,这里就不能写另外一个服务器的ip和端口,需要写另外一个服务器在eureka注册中心注册的服务名称 return restTemplate.getForObject("http://userservice/userService/user/queryUser", Result.class); } }
Nacos注册中心
Nacos是阿里巴巴的产品,现在是SpringCloud中的一个组件。相比Eureka功能更加丰富,在国内受欢迎程度较高
nacos下载地址,注意当前1版本是稳定版,2版本的还处于测试阶段
nacos启动
nacos开箱即用,前往bin目录输入命令./startup.cmd -m standalone
启动nacos
在浏览器输入:http://127.0.0.1:8848/nacos/index.html
即可,默认用户密码是nacos/nacos
服务注册
naos与eureka都遵循Spring cloud common
的接口规范,所以只需引入对应的依赖和修改对应的配置即可,其他代码都不需要动。
父工程添加nacos的jar包版本管理
<!--nacos的管理依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.2.5.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
依赖添加
<!--去除之前eureka-client的依赖包,添加nacos-client的依赖包-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
配置文件修改
配置文件只需修改一处,注册中心换成nacos即可
spring.cloud.nacos.server-addr=http://127.0.0.1:8848
负载均衡
开启负载均衡
@Bean
@LoadBalanced //开启负载均衡
public RestTemplate restTemplate(){
return new RestTemplate();
}
负载均衡的原理
负载均衡的策略
Ribbon
的负载均衡规则是一个叫做IRule
的接口来定义的,每一个子接口都是一种规则:
-
Ribbon
的负载均衡策略大概分两种:轮循(RoundRobinRule
)和随机(RandomRule
)。 -
默认策略是
ZoneAvoidanceRule
:按照zone
对服务器进行分组,按组进行轮循。 -
具体策略释义如下:
内置负载均衡规则类 规则描述 RoundRobinRule 简单轮询服务列表来选择服务器。它是Ribbon默认的负载均衡规则。 AvailabilityFilteringRule 对以下两种服务器进行忽略: (1)在默认情况下,这台服务器如果3次连接失败,这台服务器就会被设置为“短路”状态。短路状态将持续30秒,如果再次连接失败,短路的持续时间就会几何级地增加。(2)并发数过高的服务器。如果一个服务器的并发连接数过高,配置了AvailabilityFilteringRule规则的客户端也会将其忽略。并发连接数的上限,可以由客户端的<clientName>.<clientConfigNameSpace>.ActiveConnectionsLimit属性进行配置。 WeightedResponseTimeRule 为每一个服务器赋予一个权重值。服务器响应时间越长,这个服务器的权重就越小。这个规则会随机选择服务器,这个权重值会影响服务器的选择。 ZoneAvoidanceRule 以区域可用的服务器为基础进行服务器的选择。使用Zone对服务器进行分类,这个Zone可以理解为一个机房、一个机架等。而后再对Zone内的多个服务做轮询。 BestAvailableRule 忽略那些短路的服务器,并选择并发数较低的服务器。 RandomRule 随机选择一个可用的服务器。 RetryRule 重试机制的选择逻辑
负载均衡策略的配置
- 全局配置(配置在启动类中)
@Bean public IRule randomRule(){ return new RandomRule(); }
- 指定服务名称配置(配置application.properties中)
userservice.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule
负载均衡饥饿加载(配置application.properties中)
Ribbon
默认是采用懒加载,即第一次访问时才会去创建LoadBalanceClient
,请求时间会很长。
而饥饿加载则会在项目启动时创建,降低第一次访问的耗时,通过下面配置开启饥饿加载:
ribbon.eager-load.enabled=true
ribbon.eager-load.clients=userservice
nacos服务分级存储模式
# 配置服务集群分组属性
spring.cloud.nacos.discovery.cluster-name=HZ
与nacos服务分级存储模式搭配的负载均衡策略NacosRule
# 配置服务集群分组属性
userservice.ribbon.NFLoadBalancerRuleClassName=com.alibaba.cloud.nacos.ribbon.NacosRule
nacosRule负载均衡的策略:
- 优先选择同集群服务实例列表
- 本地集群找不到提供者,才去其它集群寻找,并且会报警告
- 确定了可用实例列表后,再采用随机负载均衡挑选实例
加权负载均衡
根据部署的不同服务器的优劣,可以使用加权负载均衡,来控制它的访问权重,这个是nacos可视化配置的,非常方便,权重大小介于0~1之间,如下图所示:
nacos命名空间
命名空间的作用就是隔离代码环境,即处于不同命名空间之间的服务是不能借助注册中心通信的。
nacos命名空间的创建
-
使用可视化页面创建命名空间
-
将生成的命名空间ID配置到需要放置到该命名空间下的服务中去
spring.cloud.nacos.discovery.namespace=2728a8a7-f915-45bc-8196-2c527679ecc8
-
重启该服务
nacos的临时实例和非临时实例
服务注册到nacos中的实例默认都是临时实例。
临时实例和非临时实例的差别:
- 临时实例宕机时,会从nacos的服务列表中剔除,而非临时实例则不会。
- 临时实例定时向nacos发送心跳,当nacos一段时间收不到心跳,就会认为该服务实例不健康,将其剔除出服务列表
- 非临时实例不会像nacos发送心跳,而是由nacos注册中心定时向非临时实例发送请求询问其是否健康,当nacos认为该服务实例不健康时,nacos不会剔除该实例,而是等待它重新启动起来
配置服务实例为非临时实例:
spring.cloud.nacos.discovery.ephemeral=false
注意: 一般我们不会选择非临时实例,因为这样对于nacos注册中心的服务压力就变大了。
eureka与nacos的区别
- Nacos与eureka的共同点
- 都支持服务注册和服务拉取
- 都支持服务提供者心跳方式做健康检测
- Nacos与Eureka的区别
- Nacos支持服务端主动检测提供者状态:临时实例采用心跳模式,非临时实例采用主动检测模式
- 临时实例心跳不正常会被剔除,非临时实例则不会被剔除
- Nacos支持服务列表变更的消息推送模式,服务列表更新更及时
- Nacos集群默认采用AP方式,当集群中存在非临时实例时,采用CP模式;Eureka采用AP方式
使用nacos实现动态配置管理
实现流程
具体步骤
-
在nacos可视化页面添加动态配置文件,文件名称格式:服务名称-名称空间.properties或者服务名称-名称空间.yaml
-
在动态配置文件中编辑配置信息
-
在需要引入动态配置的项目中引入nacos动态配置的依赖,并添加bootstrap.properties配置文件
<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency>
#这五个决定了去哪里读取动态配置文件 #1. 服务注册需要的信息 #eureka客户端的服务名称 spring.application.name=orderservice #2. 动态配置文件的名称空间名称 spring.profiles.active=dev #3. 动态配置文件的后缀 spring.cloud.nacos.config.file-extension=properties #4. 动态配置文件的配置文件所在的名称空间ID(public可以省略,可以与项目不在一个名称空间) spring.cloud.nacos.config.namespace=2728a8a7-f915-45bc-8196-2c527679ecc8 #5. 需要注册到nacos服务集群的地址 spring.cloud.nacos.server-addr=http://127.0.0.1:8848
注意: bootstrap.properties只是比application.properties加载的优先级更高,所以有些配置在bootstrap.properties里面配置完成后就不需要在application.properties重复配置
-
测试
//创建与之对应的配置类 import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; @Component //ConfigurationProperties注解可以注入配置文件属性值,只需前缀与该类下的属性值相结合是配置文件的key即可,并且可以实现实时感知,比@Value注入要强大 @ConfigurationProperties(prefix = "message") public class MessageConfig { private Boolean switchStatus; public Boolean getSwitchStatus() { return switchStatus; } public void setSwitchStatus(Boolean switchStatus) { this.switchStatus = switchStatus; } }
feignClient
使用feignClient代替restTemplate
原因: restTemplate存在下列问题:
- 代码可读性差,编程体验不统一
- 参数复杂URL难以维护
使用步骤
-
引入依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>
-
在启动类使用注解
@EnableFeignClients
开启feignClientimport org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.openfeign.EnableFeignClients; @EnableFeignClients //开启feignClient @SpringBootApplication public class App { public static void main(String[] args) { SpringApplication.run(App.class,args); } }
-
创建client接口映射客户端服务接口
import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @FeignClient("userservice") //服务实例名称 public interface UserServiceClient { //路径,请求方式 @RequestMapping(value = "/userService/user/queryUser",produces = "application/json;charset=utf-8",method = RequestMethod.GET) Result queryUser (); }
注意: feignClient已经自动装配了Ribbon
负载均衡策略,所以关于负载均衡方面的配置无需修改。
Feign性能优化
Feign底层的客户端实现:
-
URLConnection
:默认实现,不支持连接池 -
Apache HttpClient
:支持连接池 -
OKHttp
:支持连接池
Feign的日志级别
Feign的日志级别主要有四种:NONE、BASIC、HEADERS、FULL
Feign的优化性能主要包括:
- 使用连接池代替默认的
URLConnection
- 日志级别,最好用
basic
或none
Feign优化性能的步骤
- 引入依赖
<dependency> <groupId>io.github.openfeign</groupId> <artifactId>feign-httpclient</artifactId> </dependency>
- 配置文件
# 设置feign的日志级别 feign.client.config.default.loggerLevel=BASIC # 设置feign客户端底层实现是支持连接池的httpclient feign.httpclient.enabled=true # 设置连接池的最大连接数 feign.httpclient.max-connections=200 # 设置一个连接的最大连接数 feign.httpclient.max-connections-per-route=50
网关
网关的作用
网关的作用:
- 对用户请求做身份认证、权限校验
- 将用户请求路由到微服务,并实现负载均衡
- 对用户请求做限流
搭建Spring Cloud Gateway网关服务
-
注入依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency>
-
配置文件
server.port=10010 spring.application.name=gateway spring.cloud.nacos.server-addr=http://127.0.0.1:8848 #路由ID,必须唯一 spring.cloud.gateway.routes[0].id=userservice #路由目标地址,可以是真实的ip + port(ttp://ip:port),也可以是注册在注册中心的实例名称(lb://实例名称),lb就是负载均衡 spring.cloud.gateway.routes[0].uri=lb://userservice #路由规则,设置路由规则 spring.cloud.gateway.routes[0].predicates[0]= Path=/userService/**
注意: 网关服务的实例也需要注册到注册中心
路由规则工厂
名称 | 说明 | 示例 |
---|---|---|
After | 是某个时间点后的请求 | - After=2037-01-20T17:42:47.789-07:00[America/Denver] |
Before | 是某个时间点之前的请求 | - Before=2031-04-13T15:14:47.433+08:00[Asia/Shanghai] |
Between | 是某两个时间点之前的请求 | - Between=2037-01-20T17:42:47.789-07:00[America/Denver], 2037-01-21T17:42:47.789-07:00[America/Denver] |
Cookie | 请求必须包含某些cookie | - Cookie=chocolate, ch.p |
Header | 请求必须包含某些header | - Header=X-Request-Id, \d+ |
Host | 请求必须是访问某个host(域名) | - Host=.somehost.org,.anotherhost.org |
Method | 请求方式必须是指定方式 | - Method=GET,POST |
Path | 请求路径必须符合指定规则 | - Path=/red/{segment},/blue/** |
Query | 请求参数必须包含指定参数 | - Query=name, Jack或者- Query=name |
RemoteAddr | 请求者的ip必须是指定范围 | - RemoteAddr=192.168.1.1/24 |
Weight | 权重处理 |
路由过滤器
GatewayFilter是网关中提供的一种过滤器,可以对进入网关的请求和微服务返回的响应做处理:
路由过滤器工厂
过滤器工厂 | 功能 |
---|---|
RemoveRequestHeader | 移除请求中的一个请求头 |
AddResponseHeader | 给响应结果中添加一个响应头 |
RemoveResponseHeader | 从响应结果中移除有一个响应头 |
RequestRateLimiter | 限制请求的流量 |
AddRequestHeader | 添加请求头 |
AddRequestParameter | 添加请求参数 |
路由过滤器配置
#局部过滤器
spring.cloud.gateway.routes[0].filters[0]= AddRequestHeader=Truth,Hello Spring Cloud!
#添加全局过滤器
spring.cloud.gateway.default-filters[0]= AddRequestHeader=Truth,Hello Spring Cloud!
自定义过滤器
有些过滤业务并不简单,需要一定的逻辑代码才能实现,则gateway
提供的过滤工厂已不满足要求,可以使用自定义过滤器实现。
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
/**
* 自定义过滤器,需要实现接口GlobalFilter
*/
@Order(-1) //过滤器执行优先级,值越小优先级越高
@Component
public class LoginFileter implements GlobalFilter {
/**
*
* @param exchange 可以获取到所有请求信息
* @param chain 放行用的
* @return
*/
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
MultiValueMap<String, String> queryParams = exchange.getRequest().getQueryParams();
String user = queryParams.getFirst("user");
if("admin".equals(user)){
//放行
return chain.filter(exchange);
}
//拦截
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
return exchange.getResponse().setComplete();
}
}
注意: 自定义过滤器就是全局过滤器
过滤器的执行顺序
- 每一个过滤器都必须指定一个
int
类型的order
值,order
值越小,优先级越高,执行顺序越靠前。 -
GlobalFilter
通过实现Ordered
接口,或者添加@Order
注解来指定order
值,由我们自己指定 - 路由过滤器和
defaultFilter
的order
由Spring
指定,默认是按照声明顺序从1递增。 - 当过滤器的
order
值一样时,会按照defaultFilter
> 路由过滤器 >GlobalFilter
的顺序执行。
跨域
跨域:域名不一致就是跨域,主要包括:
- 域名不同:
www.taobao.com
和www.taobao.org
和www.jd.com
和miaosha.jd.com
- 域名相同,端口不同:
localhost:8080
和localhost8081
跨域问题:浏览器禁止请求的发起者与服务端发生跨域ajax请求,请求被浏览器拦截的问题
解决方案:CORS
gateway解决跨域的配置:
#跨域解决
#解决options请求被拦截的问题 (options请求就是浏览器向服务器询问该请求是否可以跨域)
spring.cloud.gateway.globalcors.add-to-simple-url-handler-mapping=true
#允许哪些网站的跨域请求
spring.cloud.gateway.globalcors.cors-configurations.'[/**]'.allowed-origins[0]=http://localhost:8849
#允许的跨域ajax的请求方式
spring.cloud.gateway.globalcors.cors-configurations.'[/**]'.allowed-methods[0]=GET
spring.cloud.gateway.globalcors.cors-configurations.'[/**]'.allowed-methods[1]=POST
spring.cloud.gateway.globalcors.cors-configurations.'[/**]'.allowed-methods[2]=DELETE
spring.cloud.gateway.globalcors.cors-configurations.'[/**]'.allowed-methods[3]=PUT
spring.cloud.gateway.globalcors.cors-configurations.'[/**]'.allowed-methods[4]=OPTIONS
#允许在请求中携带的头信息
spring.cloud.gateway.globalcors.cors-configurations.'[/**]'.allowed-headers[0]=*
#是否允许携带cookie
spring.cloud.gateway.globalcors.cors-configurations.'[/**]'.allow-credentials=true
#这次跨域检测的有效期(这个值设置的越长,对系统的性能提高越好)
spring.cloud.gateway.globalcors.cors-configurations.'[/**]'.max-age=360000
部署
Docker具体使用参考文档
这里我们采用Docker-Compose
去部署微服务集群
步骤分析:
- 建立一个文件夹,里面建立多个需要部署的服务的文件夹和一个
docker-compose.yml
文件#版本 version: "3.2" #服务 services: nacos: #nacos服务 image: nacos/nacos-server environment: MODE: standalone #启动模式 ports: - "8848:8848" #暴露端口 userservice: #userservice服务 build: ./user-service orderservice: #orderservice服务 build: ./order-service gateway: #网关 build: ./gateway ports: - "10010:10010" #暴露端口
- 在每个服务文件夹下创建
Dockerfile
文件FROM java:8-alpine COPY ./app.jar /tmp/app.jar ENTRYPOINT java -jar /tmp/app.jar
- 修改所有微服务里的nacos注册中心的ip配置,因为部署后nacos的ip我们不一定知道,所以不能写死
#我们只需把ip改成集群部署对应的服务名即可,Docker-Compose会帮我们找到对应的容器 spring.cloud.nacos.server-addr=http://nacos:8848
- 将所有的微服务都打成名为app的jar包,并丢入各自的文件夹中
<build> <finalName>app</finalName> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
- 将此文件夹上传至服务器,在其
docker-compose.yml
所在目录下输入以下命令完成集群部署#1. 部署集群 [root@centos100 cloud-demo]# docker-compose up -d #2. 查看集群是否启动 [root@centos100 cloud-demo]# docker ps #3. 查看集群日志 [root@centos100 cloud-demo]# docker-compose logs -f #4. 如若发现有集群连不上nacos,查看集群启动顺序,如果nacos不是第一个启动,则会有问题,那么我们把剩下集群重新restart一下 [root@centos100 cloud-demo]# docker-compose restart gateway userservice orderservice