# lagou-3-5-springcloud
**Repository Path**: java-quickstart/lagou-3-5-springcloud
## Basic Information
- **Project Name**: lagou-3-5-springcloud
- **Description**: 第三阶段模块五
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2020-07-12
- **Last Updated**: 2023-05-30
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# 李志勇的作业 - 阶段三模块五
## 编程题
根据如下描述,改造 Spring Cloud(上)的作业,完成练习:
1)Eureka 注册中心 替换为 Nacos 注册中心
2)Config+Bus 配置中心 替换为 Nacos 配置中心
3)Feign 调用 替换为 Dubbo RPC 调用
4)使用 Sentinel 对 GateWay 网关的入口资源进行限流(限流参数自定义并完成测试即可)
注意:1)所有替换组件使用单节点即可
---
### Nginx
- 占⽤端⼝:80,实现动静分离。将静态资源 html ⻚⾯存放⾄本地磁盘,数据请求统⼀经过 GateWay ⽹关路由到下游微服务。
- 静态资源(html ⻚⾯)
访问:/xxx.html,包括登录⻚⾯ login.html、注册⻚⾯ register.html、以及成功登录之后的欢迎⻚⾯ welcome.html
- nginx 配置
```conf
server {
listen 80;
server_name localhost 127.0.0.1;
root /Users/zhiyongli/source/gitee/lagou-3-4-springcloud/static-resources/static;
index login.html;
location ~ .*\.(html|js)$ {
root /Users/zhiyongli/source/gitee/lagou-3-4-springcloud/static-resources/static;
}
location / {
proxy_pass http://localhost:9002;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
```
### 使用 nacos 注册中心和配置中心
1. 下载 nacos,使用 conf 目录的 nacos-mysql.sql 建表,修改配置文件(将配置中心的配置信息保存到 mysql)
```conf
#*************** Config Module Related Configurations ***************#
### If user MySQL as datasource:
spring.datasource.platform=mysql
### Count of DB:
db.num=1
### Connect URL of DB:
db.url.0=jdbc:mysql://192.168.56.105:3306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC
db.user=root
db.password=mysql123
```
2. 登录 nacos 管理后台,新建配置信息(db 配置,发送邮件配置等)

3. 修改微服务配置,将配置中心和注册中心指向 nacos 服务器
```conf
spring:
application:
name: lagou-service-user
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
config:
server-addr: 127.0.0.1:8848
file-extension: yaml
```
4. 启动微服务,启动成功后登陆 nacos 查看服务列表

### 使用 Dubbo RPC 调用
1. 服务接口定义抽取到 lagou-service-api 模块

2. dubbo 服务提供者实现接口定义,添加 dubbo 的@Service 注解(消费端使用@Reference 注解注入 dubbo 服务)

3. 配置 dubbo 注册中心以及扫描包,配置完成启动微服务在 nacos 注册中心查看服务列表
```conf
dubbo:
scan:
base-packages: com.lagou.user
protocol:
name: dubbo
port: -1
registry:
address: spring-cloud://localhost
cloud:
subscribed-services: lagou-service-code
```
### 使用 sentinel
1. 下载 sentinel jar 包,启动 sentinel 服务器
```sh
java -Dserver.port=8089 -jar sentinel-dashboard-1.7.1.jar
```
2. 各个 dubbo 服务添加 sentinel 相关依赖,修改配置指向 sentinel 服务器
```conf
com.alibaba.cloud
spring-cloud-starter-alibaba-sentinel
com.alibaba.csp
sentinel-apache-dubbo-adapter
```
```conf
spring:
cloud:
sentinel:
transport:
dashboard: 127.0.0.1:8089
port: 8719
```
3. 网关服务添加 sentinel 相关依赖,自定义网关规则,配置 SentinelGatewayFilter
```java
@RefreshScope
@Configuration
@EnableConfigurationProperties(RegisterFrequencyProperties.class)
public class GatewayConfiguration {
private final RegisterFrequencyProperties properties;
private final List viewResolvers;
private final ServerCodecConfigurer serverCodecConfigurer;
public GatewayConfiguration(ObjectProvider> viewResolversProvider,
ServerCodecConfigurer serverCodecConfigurer,
RegisterFrequencyProperties properties) {
this.viewResolvers = viewResolversProvider.getIfAvailable(Collections::emptyList);
this.serverCodecConfigurer = serverCodecConfigurer;
this.properties = properties;
}
@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
public SentinelGatewayBlockExceptionHandler sentinelGatewayBlockExceptionHandler() {
// Register the block exception handler for Spring Cloud Gateway.
return new SentinelGatewayBlockExceptionHandler(viewResolvers, serverCodecConfigurer);
}
@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
public GlobalFilter sentinelGatewayFilter() {
return new SentinelGatewayFilter();
}
@Bean
public BlockRequestHandler blockRequestHandler() {
return (serverWebExchange, throwable) -> ServerResponse.status(500)
.contentType(MediaType.APPLICATION_JSON_UTF8)
.body(BodyInserters.fromObject("操作太频繁,请求已被拒绝"));
}
@PostConstruct
public void doInit() {
initCustomizedApis();
initGatewayRules();
}
private void initCustomizedApis() {
Set definitions = new HashSet<>();
ApiDefinition userRegisterApi = new ApiDefinition("user_register_api")
.setPredicateItems(new HashSet() {{
add(new ApiPathPredicateItem()
.setPattern("/api/user/register/.*/.*/.*")
.setMatchStrategy(URL_MATCH_STRATEGY_REGEX));
}});
definitions.add(userRegisterApi);
GatewayApiDefinitionManager.loadApiDefinitions(definitions);
}
private void initGatewayRules() {
Set rules = new HashSet<>();
rules.add(new GatewayFlowRule("user_register_api")
.setResourceMode(SentinelGatewayConstants.RESOURCE_MODE_CUSTOM_API_NAME)
.setCount(5)
.setIntervalSec(60)
);
GatewayRuleManager.loadRules(rules);
}
}
```
4. 重新启动各个服务,登录 sentinel 控制台查看链路及操作流控和降级
