Redisson系列文章:
- 【Redisson】Redisson–基礎入門
- 【Redisson】Redisson–布隆(Bloom Filter)過濾器
- 【Redisson】Redisson–分布式鎖的使用(推薦使用)
- 【分布式鎖】Redisson分布式鎖底層原理
- 【Redisson】Redisson–限流器
一、Redisson使用遠程服務
當前有兩臺服務器連接的是同一個Redisson中間件,這兩臺服務器叫它們A節(jié)點與B節(jié)點吧。A節(jié)點可以發(fā)布一些API接口,也實現(xiàn)了它們,并向Redisson服務中心注冊。B節(jié)點向Redisson注冊中心訂閱這些API接口,因此它可以向Redisson服務器發(fā)送這些請求,這些請求最終會被注冊中心轉(zhuǎn)發(fā)到A節(jié)點。這樣,B節(jié)點就能夠通過Redisson注冊中心與A節(jié)點通信,從而實現(xiàn)遠程服務調(diào)用功能。
分布式遠程服務(Remote Service)提供了兩種類型的RRemoteService實例:
服務端(遠端)實例 - 用來執(zhí)行遠程方法(工作者實例即worker instance). 例如
RRemoteService remoteService = redisson.getRemoteService();
SomeServiceImpl someServiceImpl = new SomeServiceImpl();
// 在調(diào)用遠程方法以前,應該首先注冊遠程服務
// 只注冊了一個服務端工作者實例,只能同時執(zhí)行一個并發(fā)調(diào)用
remoteService.register(SomeServiceInterface.class, someServiceImpl);
// 注冊了12個服務端工作者實例,可以同時執(zhí)行12個并發(fā)調(diào)用
remoteService.register(SomeServiceInterface.class, someServiceImpl, 12);
客戶端(本地)實例 - 用來請求遠程方法. 例如:
RRemoteService remoteService = redisson.getRemoteService();
SomeServiceInterface service = remoteService.get(SomeServiceInterface.class);
String result = service.doSomeStuff(1L, "secondParam", new AnyParam());
二、服務端(生產(chǎn)端)實戰(zhàn)
- 首先服務器端會定義一個接口IMailService,并實現(xiàn)它IMailServiceImpl。這里注意的是,IMailService與MailDto都是在API模塊里面的,方便打包并發(fā)布。MailDto需要實現(xiàn)序列化接口,因為需要存放在Redis中并
public interface IMailService {
MailDto queryMail(Long id);
}
@Service
public class IMailServiceImpl implements IMailService {
@Autowired
private MailMapper mailMapper;
@Override
public MailDto queryMail(Long id) {
Mail mail = mailMapper.selectByPrimaryKey(id);
MailDto dto = new MailDto();
if (mail != null) {
BeanUtils.copyProperties(mail, dto);
}
return dto;
}
}
- 向Redisson注冊中心發(fā)布API。CommandLineRunner接口的功能是在SpringBoot項目啟動的時候執(zhí)行相關的功能。
@Component
public class RemoteServiceInit implements CommandLineRunner {
private static final Logger LOGGER =
LoggerFactory.getLogger(RemoteServiceInit.class);
@Autowired
private RedissonClient redisson;
@Autowired
private IMailService iMailService;
@Override
public void run(String... strings) throws Exception {
LOGGER.info("初始化Redisson遠程調(diào)度");
RRemoteService remoteService = redisson.getRemoteService();
//初始化5個并發(fā)實例
remoteService.register(IMailService.class, iMailService, 5);
}
}
三、客戶端(消費端)實戰(zhàn)
生產(chǎn)端的IMailService與MailDto最好定義在API模塊,方便打包發(fā)布。打包成jar以后,導入到消費端項目B中。消費端項目B需要與生產(chǎn)端連接相同的Redisson服務器。
@Service
public class RemoteMailService {
@Autowired
private RedissonClient redisson;
public MailDto queryMail(Long id) {
//獲取Redisson遠程服務
RRemoteService remoteService = redisson.getRemoteService();
//應答回執(zhí)超時1秒鐘,遠程執(zhí)行超時30秒鐘
RemoteInvocationOptions options = RemoteInvocationOptions.defaults();
//拿到生產(chǎn)端的接口
IMailService iMailService = remoteService.get(IMailService.class,options);
//調(diào)用
return iMailService.queryMail(id);
}
}
四、響應模式附錄
涉及到網(wǎng)絡傳輸,所以可能有傳輸失敗的情況。更多的應答模式如下。
noResult()是指遠程調(diào)用的方法,不需要有返回值。noAck()表示消費端不需要要服務端響應。
// 應答回執(zhí)超時1秒鐘,遠程執(zhí)行超時30秒鐘
RemoteInvocationOptions options = RemoteInvocationOptions.defaults();
// 無需應答回執(zhí),遠程執(zhí)行超時30秒鐘
RemoteInvocationOptions options = RemoteInvocationOptions.defaults().noAck();
// 應答回執(zhí)超時1秒鐘,不等待執(zhí)行結(jié)果
RemoteInvocationOptions options = RemoteInvocationOptions.defaults().noResult();
// 應答回執(zhí)超時1分鐘,不等待執(zhí)行結(jié)果
RemoteInvocationOptions options = RemoteInvocationOptions.defaults().
expectAckWithin(1, TimeUnit.MINUTES).noResult();
// 發(fā)送即不管(Fire-and-Forget)模式,無需應答回執(zhí),不等待結(jié)果
RemoteInvocationOptions options = RemoteInvocationOptions.defaults().noAck().noResult();
RRemoteService remoteService = redisson.getRemoteService();
YourService service = remoteService.get(YourService.class, options);
下面的這段代碼是我自己實測的。
expectResultWithin(15,TimeUnit.SECONDS)表示,如果生產(chǎn)端服務器能夠接通的話,在15秒之內(nèi)需要返回數(shù)據(jù),否則報異常No response after 15000ms for request。文章來源:http://www.zghlxwxcb.cn/news/detail-535504.html
expectAckWithin(10,TimeUnit.SECONDS)表示,生產(chǎn)端服務器需要在10秒內(nèi)有響應,否則報異常No ACK response after 10000ms for request。文章來源地址http://www.zghlxwxcb.cn/news/detail-535504.html
public MailDto queryMail(Long id) {
RRemoteService remoteService = redisson.getRemoteService();
//應答回執(zhí)超過5秒鐘,不等待執(zhí)行結(jié)果
RemoteInvocationOptions options = RemoteInvocationOptions.defaults().
expectResultWithin(15, TimeUnit.SECONDS).expectAckWithin(10,TimeUnit.SECONDS);
Long start = System.currentTimeMillis();
IMailService iMailService = remoteService.get(IMailService.class,options);
MailDto result = null;
try {
result = iMailService.queryMail(id);
}catch (Exception e){
System.out.println(e.getMessage());
}
Long end = System.currentTimeMillis();
System.out.println(end - start);
return result;
}
到了這里,關于【Redisson】Redisson--分布式遠程服務(Remote Service)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!