微服务组件快速使用
# 微服务组件快速使用
# Nacos注册中心
- 下载nacos-server服务器,并双击bin中的startup启动。用户名和密码nacos登录
- 在公共依赖common.pom文件中添加依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
2
3
4
- 在需要注册的微服务项目中,yml文件添加注册中心服务器的ip+端口和当前微服务的应用名称。最后在启动类上添加注解@EnableDiscoveryClient
spring:
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
application:
name: gulimall-coupon
2
3
4
5
6
7
# Nacos配置中心
- 在公共依赖common.pom文件中添加依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
2
3
4
- 创建bootstrap.properties(它会在springboot配置前读取),并标注配置中心服务器的ip地址+端口号,以及当前微服务的应用名称,要读取配置所在命名空间,分组名,配置名称data-id(可以读取多个配置,只要配置项名称不冲突)。
spring.application.name=gulimall-coupon
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
2
- 在配置中心添加配置集合,名称叫应用名.properties(或者是yaml文件类型),在里面可以添加任何配置。
- 后端动态获取配置@RefreshScope,动态获取并刷新配置。在变量上标注@Value("${配置项的名}")获取配置中心的值。
# GateWay
- 新建一个网关的微服务程序
- 导入依赖公共依赖(注册中心,配置中心),让网关也注册到Nacos中,发现其它服务
- 启动类标注@EnableDiscoveryClient
- 在application.properties配置nacos服务器注册中心的ip地址+端口号,以及当前微服务的应用名称
- 在bootstrap.properties配置nacos配置中心ip地址+端口。
- 在application.yml配置网关规则
spring:
cloud:
gateway:
routes:
2
3
4
# Feign
在调用服务的调用方配置feign接口。
- 定义Feign接口,注解@FeignClient("gulimall-coupon")指明远程调用的Nacos微服务名称
- 在启动类注解@EnableFeignClients开启Feign远程调用,注意路径要写全(controller+方法完整请求路径)。不同服务通信关键json数据转换模型是一致的,发送接收数据对象类型不一样也可以。
@FeignClient("gulimall-coupon")
public interface CouponFeignService {
@PostMapping("/coupon/spubounds/save")
R saveSpuBounds(@RequestBody SpuBoundTo spuBoundTo);
}
2
3
4
5
- 在需要调用远程服务的service或者controller自动装配feign接口
@Autowired
private CouponFeignService couponFeignService;
2
- 注意:
- 除了直接给Nacos微服务发送请求外,还可以过网关给Gateway发请求(负载均衡)。
- 如果远程调用失败,可以try-catch,只catch捕获异常不抛出,不回滚从而影响整个事务。
# Gateway
# 基本配置
- 添加pom依赖
- 配置yml注册中心信息,将Gateway微服务也注册到Nacos中
- 在yml中添加配置微服务网关转发配置。
- path断言表示匹配发起请求的地址为Gateway微服务IP+端口+Path,如果是则进入过滤器
- filters将请求地址进行过滤,最终转发的微服务地址为uri+rewritePath地址。
- uri中lb表示进行负载均衡,后面接访问的微服务在Nacos注册的应用名称。网关会转换成该微服务对应的ip加端口。
spring:
cloud:
gateway:
routes:
- id: product_route
uri: lb://gulimall-product
predicates:
- Path=/api/product/**
filters:
- RewritePath=/api/(?<segment>.*),/$\{segment}
2
3
4
5
6
7
8
9
10
# 解决跨域
本质上都是通过设置如下参数来实现跨域,可以通过yml配置或者声明一个@Configuration配置类。
- allowedOrigins:允许哪些网站的跨域请求
- allowedMethods:允许的跨域的请求方式
- allowedHeaders:允许在请求中携带的头信息
- allowCredentials:是否允许携带cookie
@Configuration
public class GulimallCorsConfiguration {
@Bean
public CorsWebFilter corsWebFilter(){
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration corsConfiguration = new CorsConfiguration();
//1、配置跨域
corsConfiguration.addAllowedHeader("*");
corsConfiguration.addAllowedMethod("*");
corsConfiguration.addAllowedOrigin("*");
corsConfiguration.setAllowCredentials(true);
source.registerCorsConfiguration("/**",corsConfiguration);
return new CorsWebFilter(source);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Nginx
一般来说Nginx都只是作为一个入口,连接外网到部署的微服务内网。
- 首先客户端从外部直接访问一个域名/ip时,nginx会监听server块内server_name+listen,如果域名+端口匹配则会根据后续不同的url字段交给当前server块的不同location进行代理。
- Nginx常常用来配置一个首页访问请求,整个流程:外部域名—>Nginx内server块代理到GateWay网关—>网关从根据Nacos转发给对应的微服务。
- 而进入首页后的页面跳转,对于一个前端页面而言通常是前端页面向Gateway网关发送请求。
- location块:
- root:表示匹配的请求路径都去Nginx哪个文件夹下面找。
- proxy_pass:表示所有请求都转发给哪个URL地址。

# Sentinel
导入依赖spring-cloud-starter-alibaba-sentinel
下载sentinel-dashboard控制台,并启动jar包
在微服务项目配置sentinel控制台的启动端口,微服务和控制台传输信息的端口。
具体限流配置
流控:直接,关联(关联资源的QPS超过阈值,则给当前资源降级),链路,warmup冷启动,排队等待。
熔断:A远程调用B服务时,B服务宕机或者连接超时,则需要熔断B服务,给A服务返回一个默认数据。首先给调用方A的spring配置文件添加开启feign的熔断功能feign.sentinel.enabled=true(开启后在控制台可以监控到远程服务的簇点电路),并在调用方的FeignClient声明fallback,指定降级处理类作为默认回调(声明类需要注入spring容器),在回调类中实现feign接口并重写降级方法。
@FeignClient(value="xx",fallback=SeckillFallback.class)1降级:配置降级策略,通过监测异常数和异常比例来触发。远程服务被降级处理后,触发熔断机制。
注解受保护的资源,并配置回调
@SentinelResource(value="资源名",block="blockHandler"):在方法注解后,该controller方法会出现在簇点链路上,进一步配置限流降级规则。触发限流/降级后回调block方法(方法类型,返回值都要和原函数一致)。
注意:无论是注解了受保护的url还是方法,都要配置一个统一的降级回调返回。
@Configuration
public class GulimallSeckillSentinelConfig {
public GulimallSeckillSentinelConfig() {
WebCallbackManager.setUrlBlockHandler(new UrlBlockHandler() {
@Override
public void blocked(HttpServletRequest request, HttpServletResponse response, BlockException ex) throws IOException {
R error = R.error(BizCodeEnum.TO_MANY_REQUEST.getCode(), BizCodeEnum.TO_MANY_REQUEST.getMessage());
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json");
response.getWriter().write(JSON.toJSONString(error));
}
});
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
- 对网关Gateway层限流
可以针对RouteID对官网配置的微服务key进行限流,或者设置API分组,根据匹配路径进行限流。