一、初始微服务
1 单体架构
- 将业务的所有功能集中在一个项目中开发,打成一个包部署
- 优点:架构简单、成本低、易部署;缺点:耦合度高、维护升级困难
2 分布式架构
- 根据业务功能对系统做拆分,每个业务功能模块作为独立项目开发,称为一个服务,比如一个系统的用户模块和支付模块
- 优点:耦合度低、利于升级和服务;缺点:各个服务直接的调复杂
3 微服务架构
- 单一职责:微服务拆分粒度更小,每一个服务都对应唯一的业务能力,做到单一职责
- 自治:团队独立、技术独立、数据独立,独立部署和交付
- 面向服务:服务提供统一标准的接口,与语言和技术无关
- 隔离性强:服务调用做好隔离、容错、降级,避免出现级联问题
4 微服务技术对比
5 服务拆分
5.1 原则
- 不同微服务,不要重复开发相同业务
- 微服务数据独立,不要访问其它微服务的数据库,其他服务的数据库是不知道的,所以不能直接访问
- 微服务可以将自己的业务暴露为接口,供其它微服务调用
5.2 demo
有一个订单模块和一个用户模块。两个模块相互独立,都有自己对应的数据库。根据id分别查询用户和订单,要求在订单中嵌套用户。
订单走8081端口、用户走8080端口
用户查询:
订单查询:
{"id":101,"price":699900,"name":"Apple 苹果 iPhone 12 ","num":1,"userId":1,"user":null}
可以看到,因为两个模块相互独立,没有嵌套sql,所以订单查询出来的用户为null。
解决方法:
1> 在启动类中注入RestTemplate
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
/**
* 创建RestTemplate并注入容器
* @return
*/
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
2> 在sevice方法接口中向用户模块发送http请求,查询User数据
public Order queryOrderById(Long orderId) {
// 1.查询订单
Order order = orderMapper.findById(orderId);
//2. 利用restTemplate发送http请求
String url = "http://localhost:8081/user/" + order.getUserId();
User user = restTemplate.getForObject(url, User.class);
//3. 封装user数据
order.setUser(user);
// 4.返回
return order;
}
查询结果:
{"id":101,"price":699900,"name":"Apple 苹果 iPhone 12 ","num":1,"userId":1,"user":{"id":1,"username":"柳岩","address":"湖南省衡阳市"}}
通过上述步骤就实现了一个最基本的服务拆分
二、 Eureka注册中心
1 拆分问题
如果我们的服务提供者有多个部署,多个ip地址和端口,那么消费者就不知道该调用哪一个服务,如下图:
需思考:
- order-service在发起远程调用的时候,该如何得知user-service实例的ip地址和端口?
- 有多个user-service实例地址,order-service调用时该如何选择?
- order-service如何得知某个user-service实例是否依然健康,是不是已经宕机?
2 Eureka的结构和作用
上述思考问题都需要SpringCloud中的注册中心来解决来解决,常用的就是Eureka
问题回答:
问题1:order-service如何得知user-service实例地址?
- 服务注册:user-service启动后会将自己的信息注册到eureka-server(Eureka服务端)
- eureka-server保存服务名到实例地址之间的映射
- 服务拉取:order-service根据服务名称拉取实例地址列表
问题2:order-service如何从多个user-service实例中选择具体的实例?
- order-service从实例列表中利用负载均衡算法选中一个实例地址
- 向该实例地址发起远程调用
问题3:order-service如何得知某个user-service实例是否依然健康,是不是已经宕机?
- user-service会每隔一段时间(默认30秒)向eureka-server发起请求,报告自己状态,称为心跳
- 当超过一定时间没有发送心跳时,eureka-server会认为微服务实例故障,将该实例从服务列表中剔除
- order-service拉取服务时,就能将故障实例排除了
注意:一个微服务,既可以是服务提供者,又可以是服务消费者,因此eureka将服务注册(生产者)、服务发现(消费者)等功能统一封装到了eureka-client端
3 搭建Eureka注册中心
3.1 导入依赖
<!--Eureka服务端依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
3.2 编写启动类
//使用@SpringBootApplication时 启动类要放到子包中 如com.qing下 不能直接放到java包下
@SpringBootApplication
@EnableEurekaServer
public class EurekaApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaApplication.class, args);
}
}
3.3 编写配置文件
server:
#eureka服务端口
port: 10086
spring:
application:
#eureka服务名称
name: eureka-server
eureka:
client:
#eureka地址信息
service-url:
defaultZone: http://127.0.0.1:10086/eureka
访问:http://127.0.0.1:10086 即可成功
4 服务注册(生产者)
4.1 导入依赖
<!--Eureka客户端依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
4.2 编写配置文件
spring:
application:
name: orderservice
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:10086/eureka
4.3 注册多个服务
首先点击右上角的Edit Configurations
勾选Allow parallel run
最后在配置文件中更改端口 避免冲突
5 服务发现(消费者)
4.1 导入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
4.2 编写配置文件
spring:
application:
name: orderservice
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:10086/eureka
4.3 服务拉取和负载均衡
1> 服务拉取:修改消费者接口方法中的url路径,用服务名代替ip、端口
原先的:
修改后的:
2> 负载均衡:在消费者的主启动类中的RestTemplate上添加@LoadBalanced
注解, 默认轮询
三、Ribbon
1 负载均衡原理
基本流程如下:
- 拦截我们的RestTemplate请求http://userservice/user/1
- RibbonLoadBalancerClient会从请求url中获取服务名称,也就是user-service
- DynamicServerListLoadBalancer根据user-service到eureka拉取服务列表
- eureka返回列表,localhost:8081、localhost:8082
- IRule利用内置负载均衡规则,从列表中选择一个,例如localhost:8081
- RibbonLoadBalancerClient修改请求地址,用localhost:8081替代userservice,得到http://localhost:8081/user/1,发起真实请求
2 负载均衡策略
负载均衡的规则都定义在IRule接口中,而IRule有很多不同的实现类:
不同规则的含义如下:
内置负载均衡规则类 | 规则描述 |
---|---|
RoundRobinRule | 简单轮询服务列表来选择服务器。它是Ribbon默认的负载均衡规则。 |
AvailabilityFilteringRule | 对以下两种服务器进行忽略: (1)在默认情况下,这台服务器如果3次连接失败,这台服务器就会被设置为“短路”状态。短路状态将持续30秒,如果再次连接失败,短路的持续时间就会几何级地增加。 (2)并发数过高的服务器。如果一个服务器的并发连接数过高,配置了AvailabilityFilteringRule规则的客户端也会将其忽略。并发连接数的上限,可以由客户端的..ActiveConnectionsLimit属性进行配置。 |
WeightedResponseTimeRule | 为每一个服务器赋予一个权重值。服务器响应时间越长,这个服务器的权重就越小。这个规则会随机选择服务器,这个权重值会影响服务器的选择。 |
ZoneAvoidanceRule | 以区域可用的服务器为基础进行服务器的选择。使用Zone对服务器进行分类,这个Zone可以理解为一个机房、一个机架等。而后再对Zone内的多个服务做轮询。 |
BestAvailableRule | 忽略那些短路的服务器,并选择并发数较低的服务器。 |
RandomRule | 随机选择一个可用的服务器。 |
RetryRule | 重试机制的选择逻辑 |
默认的实现就是ZoneAvoidanceRule,是一种轮询方案
3 自定义负载均衡策略
3.1 代码方式
编写一个IRoleConfig配置类,注入自定义配置规则(全局配置 对任何服务都生效)
@Configuration
public class IRoleConfig {
@Bean
public IRule myIRole() {
//随机策略
return new RandomRule();
//简单轮询策略
//return new RoundRobinRule();
}
}
3.2 配置文件方式
application.yml文件中,添加新的配置(指定服务配置)
# 给某个微服务配置负载均衡规则,这里是userservice服务
userservice:
ribbon:
# 负载均衡规则
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
注意:一般用默认的负载均衡规则,不做修改。
4 饥饿加载
可以看到第一次访问时用时398ms,第二次只用了18ms,两次请求耗时相差几十倍。
这就是Ribbon默认的懒加载策略,即第一次访问时才会去创建LoadBalanceClient,请求时间会很长。
可以通过配置饥饿加载,让项目启动时加载,减少第一次访问的时间:
ribbon:
eager-load:
#开启饥饿加载
enabled: true
#指定服务名生效
clients:
- userservice
#- xxxservice
四、Nacos注册中心
1 安装启动
安装后点击bin目录下的startup.cmd,第一次直接点击启动会报错。原因是nacos默认的都是集群模式,这里单机测试就是用单机模式。
解决方法:
1> 右键点击编辑startup.cmd
2> 通过cmd启动,输入命令startup.cmd -m standalone
(推荐使用)
启动成功后访问http://192.168.137.1:8848/nacos/index.html
账号:nacos 密码:nacos
2 服务注册
2.1 引入依赖
<!--父工程引入SpringCloudAlibaba的nacos管理依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.2.6.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--生产者消费者引入nacos-discovery依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
引入nacos-discovery依赖后需要注释掉原来的Eureka依赖
2.2 修改配置文件
application.yml中添加nacos地址:
spring:
cloud:
nacos:
server-addr: localhost:8848
要注释掉之前的Eureka配置
配置好后启动生产者消费者,在Nacos控制台就可以看到服务注册成功
3 配置集群
一个服务可以有多个实例,如一个user-service可以有127.0.0.1:8081 127.0.0.1:8082 127.0.0.1:8083。每个实例又可以分布在不同的机房,如
- 127.0.0.1:8081,在上海机房
- 127.0.0.1:8082,在上海机房
- 127.0.0.1:8083,在杭州机房
Nacos就将同一机房内的实例 划分为一个集群。
3.1 修改配置文件
spring:
cloud:
nacos:
server-addr: localhost:8848
discovery:
#集群名 HZ代指杭州
cluster-name: HZ
配置成功后,启动两个HZ实例,再启动一个SH实例,可以在nacos控制台看到:
3.2 修改集群负载均衡
1> 修改order-service(消费者)的application.yml文件,修改负载均衡规则:
userservice:
ribbon:
# 负载均衡规则 NacosRule:优先选择本地集群 本地集群内部随机访问
NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule
2> 之前order-service(消费者)配置了自定义负载均衡IRole规则的需要将其注销
4实例权重配置
在nacos控制台可以修改每个实例的权重。服务器设备性能有差异,部分实例所在机器性能较好,另一些较差,我们希望性能好的机器承担更多的用户请求。
在控制台点击编辑就可以修改实例的权重,权重比越大,访问的次数越多,如果实例权重修改为0,则不会访问这个实例。
5 环境隔离
Nacos提供了namespace来实现环境隔离功能。
- nacos中可以有多个namespace
- namespace下可以有group、service等
- 不同namespace之间相互隔离,例如不同namespace的服务互相不可见
1> nacos控制台创建namespace
2> 修改配置文件
只需要在配置文件中新增一个namespace: spaceId
即可,spaceId是命名空间的ID,可以在控制台查看
6 Eureka、Nacos区别
Nacos的服务实例分为两种l类型:
- 临时实例:如果实例宕机超过一定时间,会从服务列表剔除,默认的类型。
- 非临时实例:如果实例宕机,不会从服务列表剔除,也可以叫永久实例。
在配置文件中设置非临时实例
spring:
cloud:
nacos:
discovery:
# 设置为非临时实例
ephemeral: false
nacos工作原理:
Nacos与eureka的共同点
- 都支持服务注册和服务拉取
- 都支持服务提供者心跳方式做健康检测
Nacos与Eureka的区别
- Nacos支持服务端主动检测提供者状态:临时实例采用心跳模式,非临时实例采用主动检测模式
- 临时实例心跳不正常会被剔除,非临时实例则不会被剔除
- Nacos支持服务列表变更的消息推送模式(pull+push),服务列表更新更及时;Eureka是30s更新一次,更新不够及时
- Nacos集群默认采用AP方式,当集群中存在非临时实例时,采用CP模式;Eureka采用AP方式
五 Nacos配置管理
当微服务配置的实例越来越多时,管理一个实例的配置文件就会很繁琐,特别是一些相同的、经常修改的配置,如时间格式等。
可以在Nacos管理控制台进行配置管理,Nacos一方面可以将配置集中管理,另一方可以在配置变更时,及时通知微服务,实现配置的热更新。
1 统一配置
1.1 nacos添加配置文件
点击配置管理->配置列表->新增配置
1.2 配置拉取
微服务要拉取nacos管理端的配置文件,与本地配置文件合并后才能完成项目启动
因此spring引入了一种新的配置文件:bootstrap.yaml文件,会在application.yml之前被读取,流程如下:
1》 在生产者pom文件中引入依赖
<!--nacos配置管理依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
2》 添加bootstrap.yaml
spring:
application:
name: userservice # 服务名称
profiles:
active: dev #开发环境,这里是dev
cloud:
nacos:
server-addr: localhost:8848 # Nacos地址
config:
file-extension: yaml # 文件后缀名
这里会根据${spring.application.name}-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
作为文件id,来读取配置
与nacos控制台的配置文件名(userservice-dev.yaml)一一对应
测试:
@Slf4j
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
//用 @Value拉取远程配置
@Value("${pattern.dateformat}")
private String dateformat;
@GetMapping("now")
public String now(){
return LocalDateTime.now().format(DateTimeFormatter.ofPattern(dateformat));
}
// ...略
}
1.3 出现问题
如果启动报错,大部分原因可能如下:
- nacos控制台的配置文件和服务列表不在同一个环境下,所属namespace不同,测试时我都放在public环境下
- nacos控制台的配置文件名和本地bootstrap.yaml文件中没有一一对应
- bootstrap.yaml配置文件加载不出,需添加cloud-bootstrap依赖
<!--cloud-bootstrap-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
<version>3.0.3</version>
</dependency>
2 配置热更新
热更新:每当我们修改了nacos控制台中的配置时,希望不需要重启服务就能实现动态修改,这就是配置文件热更新
2.1 @Value+@RefreshScope
在@Value注入的变量所在类上添加注解@RefreshScope:
2.2 @ConfigurationProperties
使用@ConfigurationProperties注解代替@Value注解+@RefreshScope注解
可以新建一个配置类PatternPropertiesConfig,在里面拉取nacos控制台中所有的配置:
@Data
@Component
@ConfigurationProperties(prefix = "pattern")
public class PatternPropertiesConfig {
private String dateformat;
}
使用时只需要注入配置类就行
@Autowired
PatternPropertiesConfig patternPropertiesConfig;
3 配置共享
微服务启动时,会去nacos读取多个配置文件,例如:
[spring.application.name]-[spring.profiles.active].yaml
,例如:userservice-dev.yaml(开发环境)[spring.application.name].yaml
,例如:userservice.yaml(全局环境)
而[spring.application.name].yaml
(userservice.yaml)不包含环境,因此可以被多个环境共享
3.1 测试
1》 在nacos控制台新建一个环境配置,取名userservice.yaml,作为全局环境配置
2》 PatternPropertiesConfig配置类中新增envSharedValue属性值
3》 修改bootstrap.yaml配置,将发布版本改为test,重启userservice8082端口,8081仍然为dev版本不变
可以看到8082端口拿不到8081dev版本的dateformat值
3.2 配置共享的优先级
当nacos、服务本地同时出现相同属性时,优先级有高低之分:
4 搭建nacos集群
搭建集群的基本步骤:
- 搭建数据库,初始化数据库表结构
- 下载nacos安装包
- 配置nacos
- 启动nacos集群
- nginx反向代理
4.1 搭建数据库
新建一个数据库,命名为nacos,执行SQL
CREATE TABLE `config_info` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
`data_id` varchar(255) NOT NULL COMMENT 'data_id',
`group_id` varchar(255) DEFAULT NULL,
`content` longtext NOT NULL COMMENT 'content',
`md5` varchar(32) DEFAULT NULL COMMENT 'md5',
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',
`src_user` text COMMENT 'source user',
`src_ip` varchar(50) DEFAULT NULL COMMENT 'source ip',
`app_name` varchar(128) DEFAULT NULL,
`tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段',
`c_desc` varchar(256) DEFAULT NULL,
`c_use` varchar(64) DEFAULT NULL,
`effect` varchar(64) DEFAULT NULL,
`type` varchar(64) DEFAULT NULL,
`c_schema` text,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_configinfo_datagrouptenant` (`data_id`,`group_id`,`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_info';
/******************************************/
/* 数据库全名 = nacos_config */
/* 表名称 = config_info_aggr */
/******************************************/
CREATE TABLE `config_info_aggr` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
`data_id` varchar(255) NOT NULL COMMENT 'data_id',
`group_id` varchar(255) NOT NULL COMMENT 'group_id',
`datum_id` varchar(255) NOT NULL COMMENT 'datum_id',
`content` longtext NOT NULL COMMENT '内容',
`gmt_modified` datetime NOT NULL COMMENT '修改时间',
`app_name` varchar(128) DEFAULT NULL,
`tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_configinfoaggr_datagrouptenantdatum` (`data_id`,`group_id`,`tenant_id`,`datum_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='增加租户字段';
/******************************************/
/* 数据库全名 = nacos_config */
/* 表名称 = config_info_beta */
/******************************************/
CREATE TABLE `config_info_beta` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
`data_id` varchar(255) NOT NULL COMMENT 'data_id',
`group_id` varchar(128) NOT NULL COMMENT 'group_id',
`app_name` varchar(128) DEFAULT NULL COMMENT 'app_name',
`content` longtext NOT NULL COMMENT 'content',
`beta_ips` varchar(1024) DEFAULT NULL COMMENT 'betaIps',
`md5` varchar(32) DEFAULT NULL COMMENT 'md5',
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',
`src_user` text COMMENT 'source user',
`src_ip` varchar(50) DEFAULT NULL COMMENT 'source ip',
`tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_configinfobeta_datagrouptenant` (`data_id`,`group_id`,`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_info_beta';
/******************************************/
/* 数据库全名 = nacos_config */
/* 表名称 = config_info_tag */
/******************************************/
CREATE TABLE `config_info_tag` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
`data_id` varchar(255) NOT NULL COMMENT 'data_id',
`group_id` varchar(128) NOT NULL COMMENT 'group_id',
`tenant_id` varchar(128) DEFAULT '' COMMENT 'tenant_id',
`tag_id` varchar(128) NOT NULL COMMENT 'tag_id',
`app_name` varchar(128) DEFAULT NULL COMMENT 'app_name',
`content` longtext NOT NULL COMMENT 'content',
`md5` varchar(32) DEFAULT NULL COMMENT 'md5',
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',
`src_user` text COMMENT 'source user',
`src_ip` varchar(50) DEFAULT NULL COMMENT 'source ip',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_configinfotag_datagrouptenanttag` (`data_id`,`group_id`,`tenant_id`,`tag_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_info_tag';
/******************************************/
/* 数据库全名 = nacos_config */
/* 表名称 = config_tags_relation */
/******************************************/
CREATE TABLE `config_tags_relation` (
`id` bigint(20) NOT NULL COMMENT 'id',
`tag_name` varchar(128) NOT NULL COMMENT 'tag_name',
`tag_type` varchar(64) DEFAULT NULL COMMENT 'tag_type',
`data_id` varchar(255) NOT NULL COMMENT 'data_id',
`group_id` varchar(128) NOT NULL COMMENT 'group_id',
`tenant_id` varchar(128) DEFAULT '' COMMENT 'tenant_id',
`nid` bigint(20) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`nid`),
UNIQUE KEY `uk_configtagrelation_configidtag` (`id`,`tag_name`,`tag_type`),
KEY `idx_tenant_id` (`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_tag_relation';
/******************************************/
/* 数据库全名 = nacos_config */
/* 表名称 = group_capacity */
/******************************************/
CREATE TABLE `group_capacity` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`group_id` varchar(128) NOT NULL DEFAULT '' COMMENT 'Group ID,空字符表示整个集群',
`quota` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '配额,0表示使用默认值',
`usage` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '使用量',
`max_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个配置大小上限,单位为字节,0表示使用默认值',
`max_aggr_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '聚合子配置最大个数,,0表示使用默认值',
`max_aggr_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个聚合数据的子配置大小上限,单位为字节,0表示使用默认值',
`max_history_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '最大变更历史数量',
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_group_id` (`group_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='集群、各Group容量信息表';
/******************************************/
/* 数据库全名 = nacos_config */
/* 表名称 = his_config_info */
/******************************************/
CREATE TABLE `his_config_info` (
`id` bigint(64) unsigned NOT NULL,
`nid` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`data_id` varchar(255) NOT NULL,
`group_id` varchar(128) NOT NULL,
`app_name` varchar(128) DEFAULT NULL COMMENT 'app_name',
`content` longtext NOT NULL,
`md5` varchar(32) DEFAULT NULL,
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`src_user` text,
`src_ip` varchar(50) DEFAULT NULL,
`op_type` char(10) DEFAULT NULL,
`tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段',
PRIMARY KEY (`nid`),
KEY `idx_gmt_create` (`gmt_create`),
KEY `idx_gmt_modified` (`gmt_modified`),
KEY `idx_did` (`data_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='多租户改造';
/******************************************/
/* 数据库全名 = nacos_config */
/* 表名称 = tenant_capacity */
/******************************************/
CREATE TABLE `tenant_capacity` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`tenant_id` varchar(128) NOT NULL DEFAULT '' COMMENT 'Tenant ID',
`quota` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '配额,0表示使用默认值',
`usage` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '使用量',
`max_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个配置大小上限,单位为字节,0表示使用默认值',
`max_aggr_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '聚合子配置最大个数',
`max_aggr_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个聚合数据的子配置大小上限,单位为字节,0表示使用默认值',
`max_history_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '最大变更历史数量',
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_tenant_id` (`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='租户容量信息表';
CREATE TABLE `tenant_info` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
`kp` varchar(128) NOT NULL COMMENT 'kp',
`tenant_id` varchar(128) default '' COMMENT 'tenant_id',
`tenant_name` varchar(128) default '' COMMENT 'tenant_name',
`tenant_desc` varchar(256) DEFAULT NULL COMMENT 'tenant_desc',
`create_source` varchar(32) DEFAULT NULL COMMENT 'create_source',
`gmt_create` bigint(20) NOT NULL COMMENT '创建时间',
`gmt_modified` bigint(20) NOT NULL COMMENT '修改时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_tenant_info_kptenantid` (`kp`,`tenant_id`),
KEY `idx_tenant_id` (`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='tenant_info';
CREATE TABLE `users` (
`username` varchar(50) NOT NULL PRIMARY KEY,
`password` varchar(500) NOT NULL,
`enabled` boolean NOT NULL
);
CREATE TABLE `roles` (
`username` varchar(50) NOT NULL,
`role` varchar(50) NOT NULL,
UNIQUE INDEX `idx_user_role` (`username` ASC, `role` ASC) USING BTREE
);
CREATE TABLE `permissions` (
`role` varchar(50) NOT NULL,
`resource` varchar(255) NOT NULL,
`action` varchar(8) NOT NULL,
UNIQUE INDEX `uk_role_permission` (`role`,`resource`,`action`) USING BTREE
);
INSERT INTO users (username, password, enabled) VALUES ('nacos', '$2a$10$EuWPZHzz32dJN7jexM34MOeYirDdFAZm2kuWj7VEOJhhZkDrxfvUu', TRUE);
INSERT INTO roles (username, role) VALUES ('nacos', 'ROLE_ADMIN');
4.2 配置Nacos
1》 进入nacos的conf目录,修改配置文件cluster.conf.example,重命名为cluster.conf:
2》 然后添加内容:
127.0.0.1:8845
127.0.0.1.8846
127.0.0.1.8847
3》 修改application.properties文件,修改数据库配置
数据库的账号密码和数据库名要正确
4》 启动nacos,因为是集群启动,所以不需要在cmd窗口加-M参数了 直接双击startup.cmd即可
4.3 启动nacos
将nacos文件夹复制三份,分别命名为:nacos1、nacos2、nacos3
然后分别修改三个文件夹中的application.properties,
nacos1:
server.port=8845
nacos2:
server.port=8846
nacos3:
server.port=8847
4.4 Nginx反向代理
修改conf/nginx.conf文件,配置如下:
upstream nacos-cluster {
server 127.0.0.1:8845;
server 127.0.0.1:8846;
server 127.0.0.1:8847;
}
server {
listen 80;
server_name localhost;
location /nacos {
proxy_pass http://nacos-cluster;
}
}
需加载http括号中
启动ngnix,访问http://localhost/nacos即可。
因为配置了ngnix代理,所以代码中所有的nacos地址都需要改成localhost:80