1、服务提供者
配置application.yml文件
server:
port: 8083 #项目端口
spring:
application:
name: meting-user #服务名称
dubbo:
server: true #开启dubboservice服务
registry: zookeeper://localhost:2181 #注册到注册中心
protocol: #dubbo服务提供者使用的协议及暴露端口
name: dubbo
port: 20881
服务提供者接口实现(定义接口类一般放在服务提供者和消费者都依赖的包下)
import com.alibaba.dubbo.config.annotation.Service;
@Component //注册到spring容器
//1、声明服务提供类型,记得是dubbo目录下的service包;2、服务提供者使用轮询负载均衡策略
//服务端缓存,缓存到本地;针对于热点数据,量少
@Service(interfaceClass = UserApi.class,loadbalance = "roundrobin",cache = "lru")
public class UserApiImpl implements UserApi {
@Autowired
private MoocUserTMapper userTMapper;
@Override
public String sendMessage(String message) {
System.err.println("你好呀!" + message);
return "你好呀!" + message;
}
}
启动服务提供者服务
@SpringBootApplication(scanBasePackages = {"com.stylefeng.guns"}) //扫描该目录下的bean
@EnableDubboConfiguration //自动向spring容器加载dubbo的配置
public class UserApplication {
public static void main(String[] args) {
SpringApplication.run(UserApplication.class, args);
}
}
2、 服务消费者
配置application.yml文件
server:
port: 80 #项目端口
spring:
application:
name: meting-geteway #服务名称
dubbo:
server: true #开启dubbo服务
registry: zookeeper://localhost:2181 #订阅注册中心,然后拉取服务到本地
调用服务提供者服务(dubbo默认启动时检查服务提供方是否正常启动)
@RestController
public class AuthController {
// check:检查提供服务者是否正常启动,默认true检查; interfaceClass:提供服务接口类型
//async设置userApi所有的方法都是异步调用,如果一个接口有需要和不需要异步调用的接口,分两个接口写
@Reference(interfaceClass = UserApi.class,check = false,async = true)
private UserApi userApi;
@RequestMapping(value = "${jwt.auth-path}")
public ResponseDto<UserInfo> createAuthenticationToken(AuthRequest authRequest) {
//测试调用userApi服务
userApi.sendMessage("经过JWT的auth路径");
}
}
启动服务消费者
@SpringBootApplication(scanBasePackages = {"com.stylefeng.guns"})
@EnableDubboConfiguration
@EnableAsync //激活异步调用
public class GeteWayApplication {
public static void main(String[] args) {
SpringApplication.run(GeteWayApplication.class, args);
}
}
三、负载均衡策略
负载均衡是我们处理高并发、缓解网络压力和进行服务端扩容的重要手段之一,但是一般情况下我们所说的负载均衡通常都是指服务端负载均衡,服务端负载均衡又分为两种,一种是硬件负载均衡,还有一种是软件负载均衡。
策略名称 | 作用描述 |
---|---|
random | 随机,dubbo默认随机,设置权重没啥效果 |
roundrobin | 轮询(生产使用多),按公约后的权重设置轮询比率 |
leastactive: | 最少活跃调用数(生产使用多),就是慢请求调用少,计数差异,所以优先调用快的请求 |
consistentHash | 一致性hash,相同参数请求总是发到同一服务器,memcached使用就是这个 |
1、配置位置:
①客户端负载均衡:典型的Ribbon,客户端向eureka注册中心拉取所有的服务端ip和端口,通过负载均衡策略访问对应的ip服务
②服务端负载均衡:发送请求到该服务的集群,通过负载均衡算法在多个服务中选择一个进行访问
参考 服务器端负载均衡和客户端负载均衡的区别?
使用时可以使用在服务提供者和消费者,建议使用在服务提供者方,并且可有具体到方法的负载均衡策略
四、多协议
协议名称 | dubbo | RMI | hessian |
---|---|---|---|
连接数 | 单连接 | 多连接 | 多连接 |
连接方式 | 长连接 | 短连接 | 短连接 |
传输协议 | TCP协议 | TCP协议 | HTTP协议 |
传输方式 | NIO异步传输 | 同步传输 | 同步传输 |
适用场景 | 1、数据包较小 2、消费者个数多余服务者 3、常规方式 | 1、数据包大小不一2、消费者和提供者数量相差不大 | 1、数据包大小不一2、消费者和提供者数量相差不大 |
五、异步调用
1、spring配置版
<!--服务提供者名称-->
<dubbo:application name="provide" />
<!--注册到注册中心服务-->
<dubbo:registry address="zookeeper://localhost:2181"/>
<!--服务的协议为dubbo,及暴露服务端口号设置-->
<dubbo:protocol name="dubbo" port="20880"/>
<!--本地bean配置-->
<bean id="quickStartServiceImpl" class="com.xiao.quickstartService.quickstartServiceImpl"/>
<!--实际对外暴露的接口-->
<!--timeout超时设置在服务提供者和消费者都可以,默认重试3次-->
<!--asyc不管设置在服务提供者和消费者方效果一样-->
<dubbo:service interface="com.xiao.ServiceApi" ref="quickStartServiceImpl"
timeout="4000" cache="lru"
/><!--registry="N/A" 直连方式-->
消费者具体使用如下:
//调用异步服务, 此调用会立即返回null
serviceApi.sendMessage(message);
//从RPC上下文获取Future对象
Future<String> future2 = RpcContext.getContext().getFuture();
//get方法阻塞式直到请求返回结果被唤醒
System.err.println(future2.get());
六、结果缓存
缓存类型 :
①lru:基于最近最少使用原则删除多余缓存,保持最热的数据被缓存。(常用)
②threadlocal: 当前线程缓存,比如一个页面渲染,用到很多 portal,每个 portal 都要去查用户信息,通过线程缓存,可以减少这种多余访问。
③jcache: 与 JSR107 集成,可以桥接各种缓存实现。
dubbo缓存是缓存到本地
七、分组合并
1、provide配置
public class MergeAServiceImpl implements ServiceApi {
@Override
public List<String> mergeInfo(String message) {
System.err.println("provide服务提供者,merge A 输出:" + message);
return Arrays.asList("merge A"+ message);
}
}
<!--本地bean配置-->
<bean id="MergeAServiceImpl" class="com.xiao.merge.MergeAServiceImpl"/>
<bean id="MergeBServiceImpl" class="com.xiao.merge.MergeBServiceImpl"/>
<!--实际对外暴露的接口--><!--timeout超时设置在服务提供者和消费者都可以,默认重试3次-->
<dubbo:service interface="com.xiao.ServiceApi" ref="MergeAServiceImpl" group="a" />
<dubbo:service interface="com.xiao.ServiceApi" ref="MergeBServiceImpl" group="b" />
2、consumer配置
<!--引用外暴露的接口,使用merge合并a和b分组(也可以使用*表示所有)数据-->
<dubbo:reference id="consumerService" group="a,b" merger="true" interface="com.xiao.ServiceApi" timeout="3000"/> <!--url="dubbo://localhost:20880" -->
输出如下:
[aldjkasbnlkj, aldjkasbnlkj]
①使用group分组可以使用在测试环境和开发环境设置不同的分组值,方便开发和测试
②merge和group组合使用在年度表数据合并
参考 dubbo 官方文档