Springboot + SpringCloud + Nacos + OpenFeign + Gateway
根节点相关依赖
org.springframework.boot
spring-boot-starter-parent
2.7.8
com.alibaba.cloud
spring-cloud-alibaba-dependencies
2021.0.4.0
pom
import
org.springframework.cloud
spring-cloud-dependencies
2021.0.5
pom
import
官网:https://nacos.io/zh-cn/
从GitHub下载对应版本nacos,版本对应关系:
https://github.com/alibaba/spring-cloud-alibaba/wiki/%E7%89%88%E6%9C%AC%E8%AF%B4%E6%98%8E
cmd进入nacos/bin/目录
windows启动指令(单机模式):
startup.cmd -m standalone
以集群模式启动:
startup.cmd
停止运行:
shutdown.cmd
默认端口(集群需要复制多个安装包并修改端口,按实际情况修改):修改文件/conf/application.properties
server.port=8848
访问http://localhost:8848/nacos/index.html 进入服务中心管理页面,用户名和密码默认都为nacos,此时服务列表为空
依赖:
org.springframework.boot
spring-boot-starter
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-discovery
在yml配置文件中配置服务中心地址和服务名称(必须),指定该服务端口号
spring:
cloud:
nacos:
#服务中心
server-addr: localhost:8848
#discovery:
#集群名称
#cluster-name: USER
#命名空间 相同命名空间可以互相访问
#namespace: 156727b1-1778-482b-8c20-0321151d660b
#ephemeral: false
application:
name: user-service
server:
port: 8002
成功启动项目后,管理台会看到该服务已注册到服务列表
指定命名空间后,不同命名空间的服务不能相互访问.
集群指定后,相当于分组,可以相互访问
服务间利用http请求进行通信,可以使用RestTemplate和OpenFeign
OpenFeign比RestTemplate有一定优势
OpenFeign依赖(3.1.5):
org.springframework.cloud
spring-cloud-starter-openfeign
yml配置:
启动类添加启动Feign注解:
@EnableFeignClients
使用:"user-service"为目的目标服务名称,
@FeignClient("user-service")
public interface UserClient {
@RequestMapping("/user/{id}")
public String getUserById(@PathVariable("id") Long id);
}
注入到controller中
@Autowired
UserClient userClient;
String userById = userClient.getUserById(userId);
feign优化配置(默认使用Urlconnection,无连接池)
日志级别尽量用basic
使用 HttpClient 或 OKHttp 代替 URLConnection
日志打印使用基本配置,使用httpclient或者okhttp,启用连接池
导入httpclient依赖(11.10)
io.github.openfeign
feign-httpclient
feign:
httpclient:
enabled: true
max-connections: 200
max-connections-per-route: 50
client:
config:
default:
logger-level: basic
也可以在配置类中指定:
@Bean
public Logger.Level logLevel(){
return Logger.Level.BASIC;
}
配置(客户端-service-service)负载均衡策略
导入依赖(高版本已移除ribbon)
org.springframework.cloud
spring-cloud-starter-loadbalancer
创建配置文件
@Configuration
@LoadBalancerClients(defaultConfiguration = {NacosConfig.class})
public class NacosConfig {
//2021版本已剔除ribbon
/**
* 配置客户端侧负载均衡规则 service-service
*/
@Bean
public ReactorLoadBalancer specLoadBalancer(Environment environment, LoadBalancerClientFactory loadBalancerClientFactory) {
String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
return new RoundRobinLoadBalancer(loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name);
}
}
网关也作为一个微服务需要注册到注册中心,纳入管理,实际项目中可以布置多套网关
依赖:
org.springframework.boot
spring-boot-starter
org.springframework.cloud
spring-cloud-starter-gateway
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-discovery
org.springframework.cloud
spring-cloud-starter-loadbalancer
配置端口和服务名称(必须),配置路由和跨域问题相关
server:
port: 9000
spring:
cloud:
nacos:
server-addr: localhost:8848
gateway:
routes:
- id: user-service
uri: lb://user-service
predicates:
- name: Path
args:
name: Path
value: /user/**
- id: order-service
uri: lb://order-service
predicates:
- name: Path
args:
name: Path
value: /order/**
globalcors:
# 跨域问题处理
cors-configurations:
'[/**]':
#本次跨域检测有效期毫秒
maxAge: 36000
#是否允许携带cookie
allowCredentials: true
#允许请求携带的头信息
allowed-headers:
- "*"
#允许哪些网站的跨域请求
allowed-origins:
- "http://localhost:8080"
#允许的ajax请求方式
allowed-methods:
- "GET"
- "POST"
- "PUT"
- "DELETE"
- "OPTIONS"
#解决options请求被拦截问题
add-to-simple-url-handler-mapping: true
application:
name: gateway-service
路由配置或者为
gateway:
routes:
- id: user-service
uri: lb://user-service
predicates:
- Path=/user/**
- id: order-service
uri: lb://order-service
predicates:
- Path=/order/**
-----------------------
断言工厂相关说明(简写方式)
predicates:
- Path=/provider/hello/** #断言:路径相匹配进行路由
- Before=2021-08-25T12:53:46.101+08:00[Asia/Shanghai] #匹配这个时间之前的请求
- After=2021-08-25T12:53:46.101+08:00[Asia/Shanghai] #匹配这个时间之后的请求
- Between=2021-08-25T12:53:46.101+08:00[Asia/Shanghai],2021-09-25T12:53:46.101+08:00[Asia/Shanghai] #匹配这个两个时间的请求
- Cookie=username,zzyy
- Header=X-Request-Id,\d+ #请求头要有 X-Request-Id 属性并且值为整数的正则表达式
- Host=**.atguigu.com
- Method=GET #请求方式是 GET
- Query=username,\d+ #要有参数名 username 并且值还要是证书才能路由
因为网关实际上也是通过http和其他微服务通信,也可以配置负载均衡规则(service-service)
@Configuration
@LoadBalancerClients(defaultConfiguration = GatewayConfig.class)
public class GatewayConfig {
@Bean
public ReactorLoadBalancer specLoadBalancer(Environment environment, LoadBalancerClientFactory loadBalancerClientFactory) {
String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
return new RoundRobinLoadBalancer(loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name);
}
}
其他功能:过滤
yml中配置默认过滤default-filters
或配置全局过滤器,可以指定order
@Component
public class GatewayFilter implements GlobalFilter {
@Override
public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
ServerHttpResponse response = exchange.getResponse();
log.info("gateway" + request.getURI().toString());
return chain.filter(exchange);
}
}