Ribbon的加载策略

饥饿加载

初次部署微服务后,第一次访问的时候,请求的周期会较长

第一次获取数据响应时间高达546ms

第二次只需要20ms

这种现象的原因是因为riobbon的懒加载机制

Nacos

首先需要导入依赖

其中父工程的依赖是为了管理子工程的依赖的版本

然后需要修改配置文件

部署成功

这样配置实现集群的划分

一切配置就绪,但是我本地上运行的时候出现了一些问题

报错 No instances available for userservice

检查错误原因

Nacos确实获取到了注册的信息,ResrTemplate也确实加入了LoadBalance注解

http://ip:8848/nacos/v1/ns/instance/list?serviceName=user-service使用该开放api访问发现cluster为空

检查发现Nacos中服务的Ip地址不是localhost/127.0.0.1,服务注册的ip使用了VMware的虚拟网络,相当于多块网卡,在进行服务注册时候,选中了VMware虚拟网络。

这个地址是我虚拟机的虚拟网卡地址

服务的application.yml中,加入配置:

spring.cloud.inetutils: preferred-networks=192.168.0 #服务注册时优先使用这个网段。

尝试上述办法后依然没有解决问题

最后发现是RestTemplate调用的时候服务的名称为userservice,但是我的配置文件中的服务名称是UserService,没有想到Nacos会区分大小写,之前用Eureka没有出现类似的情况,之后需要规范自己的书写习惯

配置Nacos的访问策略,NacosRule并没有什么规律,先选择本地集群,再在本地集群中以随机的方式去访问

如果设置为0.1 那么相比于 1 的权重的客户端,被选中的概率是1/10,同样,如果服务的权重被调整为0了,那么这个对应的客户端就不会被访问,这可以帮助我们,对一个集群进行更新和升级,用户不会访问这个客户端,我们可以直接升级该客户端

环境隔离

Eureka和Nacos的一些差别

相同的地方

服务消费者为了降低服务器的压力,会每隔30s向Nacos/Eureka注册中心拉取可用的实例,并缓存在本地,方便直接调用,

不同的地方

Nacos除了消费者主动拉取可用的实例,在当前实例出现问题的时候,Nacos也会主动的向消费者PUSH信息,这样更新的更加及时

Nacos中的实例,分为临时实例和非临时实例,

临时实例需要定期向注册中心注册,也就是心跳检测,表示自己依然健康,如果超过了检测期限,那么Nacos注册中心会直接删除这个实例

非临时实例不会主动的向注册中心注册,而是由Nacos注册中心主动的发起检测,如果非临时实例并不健康,Nacos也不会删除该实例,而是在实例列表做对应的标记,等待其恢复

临时实例和非临时实例的注册

spring.cloud.nacos.discovery.ephemeral=ture是默认设置 ,表示是临时实例

停掉服务后,直接消失了

spring.cloud.nacos.discovery.ephemeral=false 表示是非临时实例

关闭之后

总结

Nacos配置管理

为什么要加入bootstrap.yaml类呢

因为启动项目的时候项目会把Nacos上的配置与项目内的application.yml合并起来,项目启动的时候首先需要知道Nacos上对应的配置类的访问方式,而访问方式又在application中,所以需要设置一个优先级高于application的配置,来存放Nacos的各种配置,在项目启动的时候,会优先访问bootstrap来读取Nacos的相关配置,比如访问路径,这样就可以把Nacos上对应的配置与项目内部的application结合起来了

Nacos配置自动刷新

微服务的配置共享

上面调整一下UserService无法读取到Nacos的UserService-dev.yaml

当本地与Nacos时冲突的时候

Nacos集群配置

首先创建nacos集群的数据库

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');

然后配置nacos

删掉后缀的example

编辑添加内容

然后修改application.properties文件,添加数据库配置

之后负责2份nacos,修改对应的端口号

之后分别启动,这时候启动不需要加 -m standalone 默认的启动方式就是集群启动

修改nginx集群启动的配置

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;
}

}

之后就可以直接通过localhost/nacos访问了

修改项目的nacos访问地址为127.0.0.1:80(反向代理的地址)

Http客户端Feign

实际操作

在运行的时候,我遇到了一个问题,UserService实例启动一直失败,报错是找不到Nacos的地址

可是我在bootstarp中已经配置的Nacos的地址,之后检查发现原来Nacos的注册中心的配置和Nacos的配置中心的配置是需要分开分别配置的,我之前只配置了Nacos的配置中心地址,忽略了注册中心的配置,这导致Nacos一直用的默认的8848端口,在我配置了Nginx的反向代理之后已经失效,不起作用了

修改如下

获取成功

查看IDEA的日志,发现Feign顺便还完成了负载均衡

自定义Feign的配置

上手实验

方式一

方式二

成功

Feign的性能优化

实现

第一步 引入对应的包

第二步 创建feign-api的对应结构

第三步 引入创建好的feign-api

第四步 解决无法自动装配的问题

完成

统一网关Gateway

没有全部满足,访问失败

过滤器的执行顺序

底层采用Adapter模式,最终所有的过滤器都会被转换成GatewayFilter,并且形成一条过滤器链

解决跨域的代码

spring:
cloud:
gateway:
globalcors: # 全局的跨域处理
add-to-simple-url-handler-mapping: true # 解决options请求被拦截问题
corsConfigurations:
'[/**]':
allowedOrigins: # 允许哪些网站的跨域请求
- "http://localhost:8090"
- "http://www.leyou.com"
allowedMethods: # 允许的跨域ajax的请求方式
- "GET"
- "POST"
- "DELETE"
- "PUT"
- "OPTIONS"
allowedHeaders: "*" # 允许在请求中携带的头信息
allowCredentials: true # 是否允许携带cookie
maxAge: 360000 # 这次跨域检测的有效期