我们以用户服务为例来对 springboot dubbo nacos sentinel 进行整合,我们现在有一个根据用户ID获取用户详情的接口,需要服务化给其他业务使用,dubbo 作为RPC访问框架,nacos做服务注册中心,sentinel 做限流 来保护用户服务。新建了一个工程,工程目录如下:
user-api :用户服务的API 包括接口定义,请求参数,返回参数 服务提供者(user-provider)和服务消费者使用(user-comsumer)
user-provider:用户服务的提供者
user-comsumer:用户服务消费者 消费者本不应该写在这个工程,我为方便就写在一起。
整合需要用到nacos 和 Sentinel Dashboard 所以先安装
1.nacos安装
nacos安装参考我的另一篇文章:https://blog.csdn.net/lj1314ailj/article/details/98509699
2.Sentinel Dashboard 安装
下载地址:https://github.com/alibaba/Sentinel/releases
我下载的地址jar:https://github.com/alibaba/Sentinel/releases/download/1.6.3/sentinel-dashboard-1.6.3.jar
启动:
注意:启动 Sentinel 控制台需要 JDK 版本为 1.8 及以上版本。
使用如下命令启动控制台:
java -Dserver.port=8888 -Dcsp.sentinel.dashboard.server=localhost:8888 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.6.3.jar
其中 -Dserver.port=8888 用于指定 Sentinel 控制台端口为 8888
访问:http://localhost:8888
从 Sentinel 1.6.0 起,Sentinel 控制台引入基本的登录功能,默认用户名和密码都是 sentinel。
package com.lvzhu.user.api;
import com.lvzhu.user.resp.User;
/**
* @author lvzhu.
* Time 2019-08-05 17:59
* Desc 文件描述
*/
public interface UserService {
/**
*
* 获取用户信息
* @param id
* @return
*/
User getUser(Long id);
}
b.返回实体定义
package com.lvzhu.user.resp;
import java.io.Serializable;
/**
* @author lvzhu.
* Time 2019-08-05 17:59
* Desc 文件描述
*/
public class User implements Serializable {
private static final long serialVersionUID = 1008450983070357113L;
/**
* 主键ID
*/
private Long id;
/**
* 用户名
*/
private String userName;
/**
* 年龄
*/
private Integer age;
/** 省略get set**/
}
a.整合springboot dubbo nacos
pom.xml 添加
org.apache.dubbo
dubbo-spring-boot-starter
2.7.1
org.apache.dubbo
dubbo
2.7.3
org.apache.dubbo
dubbo-registry-nacos
2.7.3
com.alibaba.nacos
nacos-client
1.1.1
com.alibaba.spring
spring-context-support
1.0.2
参考文章:http://dubbo.apache.org/zh-cn/docs/user/references/registry/nacos.html
b. dubbo整合sentinel
pom.xml 添加
com.alibaba.csp
sentinel-apache-dubbo-adapter
1.6.3
com.alibaba.csp
sentinel-transport-simple-http
1.6.3
需要注意 dubbo 版本 整合时没有注意被坑了。
dubbo 版本 Apache Dubbo 2.7.x 及以上版本 sentinel-apache-dubbo-adapter
对于Dubbo 2.6.x 及以下版本 sentinel-dubbo-adapter
如果dubbo版本使用2.7.x 使用了sentinel-dubbo-adapter jar服务调用时会出问题错误如下:
java.lang.NoSuchMethodError: com.alibaba.dubbo.rpc.RpcContext.setAttachment
sentinel 和更多主流框整合:
https://github.com/alibaba/Sentinel/wiki/%E4%B8%BB%E6%B5%81%E6%A1%86%E6%9E%B6%E7%9A%84%E9%80%82%E9%85%8D
c.application.properties 配置
spring.application.name=springboot-user-provider
##nacos 配置中心
dubbo.config-center.address=nacos://127.0.0.1:8848
dubbo.config-center.app-name=springboot-user-provider
##dubbo 服务扫描包
dubbo.scan.base-packages=com.lvzhu.user.biz
##dubbo.metadata-report.address=zookeeper://127.0.0.1:2181
##dubbo.metadata-report.address=nacos://127.0.0.1:8848
dubbo.protocol.name=dubbo
dubbo.protocol.port=20880
dubbo.application.name=springboot-user-provider
##nacos 注册中心 用zookeeper只需要把地址改为 zookeeper://127.0.0.1:2181
dubbo.registry.address=nacos://127.0.0.1:8848
##dubbo.registry.simplified=true
nacos 既可以做注册中心也可以做配置中心
d.UserServiceImpl 用户实现类
package com.lvzhu.user.biz;
import com.lvzhu.user.api.UserService;
import com.lvzhu.user.resp.User;
import org.apache.dubbo.config.annotation.Service;
/**
* @author lvzhu.
* Time 2019-08-05 18:16
* Desc 文件描述
*/
@Service(loadbalance = "random",cluster = "failsafe")
public class UserServiceImpl implements UserService {
/**
* 获取用户信息
*/
@Override
public User getUser(Long id) {
User user = new User();
user.setAge(2+id.intValue());
user.setUserName("LVZHU"+id);
user.setId(id);
System.out.println("Come in getUser()");
return user;
}
}
e.UserProviderApplication 启动类
package com.lvzhu.user;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class UserProviderApplication {
public static void main(String[] args) {
SpringApplication.run(UserProviderApplication.class, args);
}
}
这样用户服务端可以使用了
3.user-comsumer 用服务消费者编写
a. pom.xml 同服务提供者基本相同只是 spring-boot-starter 变成了spring-boot-starter-web
org.springframework.boot
spring-boot-starter-web
b.application.properties 如下
spring.application.name=springboot-user-comsumer
server.port=8081
dubbo.scan.base-packages=com.lvzhu.user.client
dubbo.application.name=springboot-user-comsumer
## dubbo.registry.address=zookeeper://127.0.0.1:2181
dubbo.registry.address=nacos://127.0.0.1:8848
d.UserClient
package com.lvzhu.user.client;
import com.lvzhu.user.api.UserService;
import com.lvzhu.user.resp.User;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.stereotype.Service;
/**
* @author lvzhu.
* Time 2019-08-05 20:17
* Desc 文件描述
*/
@Service
public class UserClient {
@Reference(loadbalance = "roundrobin", cluster = "failfast", check = false)
private UserService userService;
public User getUser(Long id) {
return userService.getUser(id);
}
}
e.UserController
package com.lvzhu.user.controller;
import com.lvzhu.user.client.UserClient;
import com.lvzhu.user.resp.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
/**
* @author lvzhu.
* Time 2019-08-05 20:17
* Desc 文件描述
*/
@RestController
public class UserController {
@Autowired
private UserClient userClient;
@GetMapping("/user/{id}")
public User getUser(@PathVariable(name = "id") Long id) {
return userClient.getUser(id);
}
}
f.UserComsumerApplication启动类
package com.lvzhu.user;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class UserComsumerApplication {
public static void main(String[] args) {
SpringApplication.run(UserComsumerApplication.class, args);
}
}
1.启动用户服务提供者
运行 UserProviderApplication
运行需要添加参数 :
-Djava.net.preferIPv4Stack=true -Dcsp.sentinel.api.port=8720 -Dcsp.sentinel.dashboard.server=localhost:8888 - Dproject.name=springboot-user-provider
如下配置:
2.启动用户服务的消费者
运行UserComsumerApplication
运行需要添加参数 :
-Djava.net.preferIPv4Stack=true -Dcsp.sentinel.api.port=8721 -Dcsp.sentinel.dashboard.server=localhost:8888 -Dproject.name=springboot-user-comsumer
启动完成后:
nacos控制台 如下:
Sentinel Dashboard 如下:
需要注意:要访问一下 http://localhost:8081/user/1 才会有 springboot-user-comsumer 和 springboot-user-provider
我们对springboot-user-provider进行流控:
点击簇点链路 可以对接口和方法进行流控 ,降级。
如下新建流控 我把单机的qps设置为了1 超过1就会快速失败
当然可以对 springboot-user-comsumer 进行限流方法同上。
整合的案例:https://github.com/ljmomo/springboot-dubbo-nacos-sentinel
clone 确保 naocos 和 sentinel都启动再运行
dubbo:http://dubbo.apache.org/zh-cn/docs/user/quick-start.html
nacos:https://nacos.io/zh-cn/docs/quick-start.html
sentinel:https://github.com/alibaba/Sentinel/wiki/%E4%BB%8B%E7%BB%8D