微效劳架构案例(04):中间件集成,大众效劳封装
2019-11-18杂谈搜奇网51°c
A+ A-本文源码:GitHub·点这里 || GitEE·点这里
更新进度(共6节):
01:项目手艺选型简介,架构图解申明
02:营业架构设想,体系分层治理
03:数据库选型,营业数据设想规划
04:中间件集成,大众效劳治理
一、中间件简介
中间件是基本软件的一类, 属于复用性极高的软件。处于操作体系软件与运用顺序的之间。是一种自力的体系软件,也可所以大众的效劳顺序,分布式架构体系借助中间件,可以在差别的手艺之间共享资本,或许差别的效劳直接通报信息。中间件位操作体系之上,治理计算机资本和网络通讯。是衔接两个自力运用顺序或自力体系的软件,比方:
- 音讯行列中间件,在两个效劳之间举行异步的音讯通报;
- 数据缓存中间件,缓存整合体系的热门数据,进步顺序的响应速度;
- Nginx中间件,供应负载平衡,效劳代办,等功用;
二、大众效劳简介
大众效劳,望文生义就是体系内通用的效劳,比方用户身份考证,音讯发送,监控预警,网关效劳等。
该案例的中间件和大众效劳,都是基于Feign
接口一致的体式格局供应效劳。
三、中间件集成
1、音讯中间件
RocketMq
简介
RocketMq
是一款分布式、行列模子的音讯中间件,有两个中心角色:音讯生产者和音讯消费者。作为高并发体系的中心组件之一,可以协助营业体系解构进步体系稳定性。
- 运用流程
- 音讯生产者
@Component
public class MsgSendService {
@Resource
private ProducerConfig producerConfig ;
public void sendMsg (MsgWrap msgWrap) {
producerConfig.sendMsg(msgWrap.getGroup(),msgWrap.getTopic(),
msgWrap.getTag(),msgWrap.getContent());
}
}
- 音讯消费者
@Component
@Consumer(group = MsgRoute.husky_group_1,
topic = MsgRoute.husky_topic_1 ,
tag = MsgRoute.husky_tag_1)
public class UserSearchListener implements MsgReadService {
@Resource
private BookEsAnalyFeign bookEsAnalyFeign ;
@Override
public void readMsg(String msg) throws Exception {
LOGGER.info("【用户搜刮音讯监听 Msg】:{}",msg) ;
// 转发要求数据剖析效劳
bookEsAnalyFeign.sendBookEsMsg(msg);
}
}
- 供应
Feign
接口
@RestController
public class UserSearchController implements UserSearchFeign {
@Resource
private SendMsgService sendMsgService ;
@Override
public void sendBookSearch(String msgContent) {
MsgWrap msgWrap = new MsgWrap() ;
msgWrap.setContent(msgContent);
msgWrap.setGroup(MsgRoute.husky_group_1);
msgWrap.setTopic(MsgRoute.husky_topic_1);
msgWrap.setTag(MsgRoute.husky_tag_1);
sendMsgService.sendMsg(msgWrap);
}
}
2、缓存中间件
Redis
简介
Redis
是一个基于内存的高性能key-value
数据库。对高并发体系供应种种场景的支持:热门数据缓存,计数器,流量削峰等。
- 运用流程
- 封装操作方法
@Service
public class RedisServiceImpl implements RedisService {
@Resource
private RedisTemplate<Object,Object> redisTemplate ;
@Override
public boolean set(Object key, Object value) {
boolean redisFlag = true ;
try {
redisTemplate.opsForValue().set(key,value);
} catch (Exception e){
redisFlag = false ;
e.printStackTrace();
}
return redisFlag ;
}
@Override
public boolean set(Object key,Object value, long expire) {
boolean redisFlag = true ;
try {
redisTemplate.opsForValue().set(key,value,expire,TimeUnit.SECONDS);
} catch (Exception e){
redisFlag = false ;
e.printStackTrace();
}
return redisFlag ;
}
@Override
public String get(Object key) {
String value = null ;
try {
value = String.valueOf(redisTemplate.opsForValue().get(key)) ;
} catch (Exception e){
e.printStackTrace();
}
return value ;
}
}
- 供应
Feign
效劳
@RestController
public class RedisController implements RedisFeign {
@Resource
private RedisService redisService ;
@Override
public boolean set (String key, String value) {
return redisService.set(key,value) ;
}
@Override
public boolean setTimeOut (String key, String value,long expire){
return redisService.set(key,value,expire) ;
}
@Override
public String get (String key) {
return redisService.get(key) ;
}
}
3、搜素中间件
ES
搜刮简介
ElasticSearch
是一个基于Lucene的搜刮效劳器。它供应了一个分布式多用户才能的全文搜刮引擎,基于RESTful
的 web接口。是当前盛行的企业级搜刮引擎。
- 运用流程
- 封装操作方法
@Service
public class BookInfoEsServiceImpl implements BookInfoEsService {
@Resource
private BookInfoRepository bookInfoRepository ;
@Override
public void batchSave(List<EsBookInfo> bookInfoList) {
bookInfoRepository.saveAll(bookInfoList) ;
}
@Override
public List<EsBookInfo> queryList() {
Iterable<EsBookInfo> bookInfoIterable = bookInfoRepository.findAll() ;
List<EsBookInfo> esBookInfoList = Lists.newArrayList(bookInfoIterable) ;
if (esBookInfoList == null){
esBookInfoList = new ArrayList<>() ;
}
return esBookInfoList;
}
@Override
public List<EsBookInfo> getByKeyWord(String keyWord) {
QueryStringQueryBuilder builder = new QueryStringQueryBuilder(keyWord);
Iterable<EsBookInfo> bookInfoIterable = bookInfoRepository.search(builder) ;
List<EsBookInfo> esBookInfoList = Lists.newArrayList(bookInfoIterable) ;
if (esBookInfoList == null){
esBookInfoList = new ArrayList<>() ;
}
return esBookInfoList ;
}
}
- 供应
Feign
效劳
@RestController
public class BookInfoEsController implements BookInfoEsFeign {
@Resource
private BookInfoEsService bookInfoEsService ;
@Override
public void batchSave(List<EsBookInfo> bookInfoList) {
bookInfoEsService.batchSave(bookInfoList);
}
@Override
public List<EsBookInfo> queryList() {
return bookInfoEsService.queryList();
}
@Override
public List<EsBookInfo> getByKeyWord(String keyWord) {
return bookInfoEsService.getByKeyWord(keyWord);
}
}
4、定时器中间件
Quartz
简介
Quartz
是由Java
编写的开源使命调理的框架,经由过程触发器设置功课定时运转划定规矩,掌握使命的执行时间。个中quartz
集群经由过程毛病切换和负载平衡的功用,能给调理器带来高可用性和伸缩性。
- 运用流程
@Component("SendMsgJob")
public class SendMsgJob implements TaskJobService {
@Resource
private SendEmailFeign sendEmailFeign ;
@Override
public void run(String param) {
String nowDate = TimeUtil.formatDate(new Date(),TimeUtil.FORMAT_01) ;
LOGGER.info("SendMsgJob Execute Time:{}",nowDate);
sendEmailFeign.sendEmail("","定时邮件关照",""+nowDate);
}
}
四、大众效劳治理
1、Token效劳
Token
效劳简介
经由过程一个大众的Token
治理效劳,对接见体系的用户身份做治理:身份令牌建立,校验,革新等。
- 运用流程
- 封装操作方法
@Service
public class UserTokenServiceImpl implements UserTokenService {
@Resource
private UserBaseMapper userBaseMapper ;
@Resource
private RedisFeign redisFeign ;
@Override
public String getToken(String userName, String passWord) throws Exception {
UserBaseExample example = new UserBaseExample() ;
example.createCriteria().andUserNameEqualTo(userName) ;
UserBase userBase = selectByExample(example) ;
if (userBase != null){
String secrete = userBase.getPassWord() ;
if (secrete.equals(passWord)) {
// 返回 Token
String value = userBase.getId().toString() ;
String publicKeyStr = RsaCryptUtil.getKey(RsaCryptUtil.PUB_KEY) ;
String token = RsaCryptUtil.encrypt(RsaCryptUtil.createPublicKey(publicKeyStr),value.getBytes()) ;
String key = RedisUtil.formatUserTokenKey(userBase.getId()) ;
redisFeign.setTimeOut(key,token, Constant.USER_TOKEN_EXPIRE) ;
return token ;
}
}
return null;
}
@Override
public Integer verifyToken(String token) throws Exception {
String privateKeyStr = RsaCryptUtil.getKey(RsaCryptUtil.PRI_KEY) ;
String userId = RsaCryptUtil.decrypt(RsaCryptUtil.createPrivateKey(privateKeyStr),
RsaCryptUtil.parseBase64Binary(token));
return Integer.parseInt(userId) ;
}
@Override
public boolean refreshToken(String token) throws Exception {
Integer userId = verifyToken(token) ;
if (userId > 0 ){
String key = RedisUtil.formatUserTokenKey(userId) ;
// 推断Token 是不是逾期
String cacheToken = redisFeign.get(key) ;
if (StringUtils.isEmpty(cacheToken)){
return false ;
}
redisFeign.setTimeOut(key,token, Constant.USER_TOKEN_EXPIRE) ;
return true ;
}
return false ;
}
}
- 供应
Feign
效劳
@FeignClient("MOPSZ-BASIS-TOKEN")
public interface UserTokenFeign {
/**
* 猎取 TOKEN
*/
@PostMapping("/token/getToken")
RespObject getToken (@RequestParam("userName") String userName,
@RequestParam("passWord") String passWord) ;
/**
* 考证 TOKEN
*/
@PostMapping("/token/verifyToken")
RespObject verifyToken (@RequestParam("token") String token) ;
/**
* 革新 TOKEN
*/
@PostMapping("/token/refreshToken")
boolean refreshToken (@RequestParam("token") String token) ;
}
2、音讯效劳
Msg
效劳简介
在一个庞杂的体系中,音讯关照是一个必备模块,平常封装体式格局重要从下面两个体式格局入手,音讯范例:用户音讯,体系音讯等,音讯吸收体式格局:邮件,短信,运用端等。
- 运用流程
- 封装邮件发送
@Service
public class SendEmailServiceImpl implements SendEmailService {
@Override
public void sendEmail(String receive, String title, String msg) {
try {
EmailUtil.sendEmail01(receive,title,msg);
} catch (Exception e){
e.printStackTrace() ;
LOGGER.info("邮件发送失利:{}",e.getMessage());
}
}
}
- 供应
Feign
效劳
@FeignClient("MOPSZ-BASIS-MSGBOX")
public interface SendEmailFeign {
/**
* 发送Email
*/
@PostMapping("/msgBox/sendEmail")
void sendEmail (@RequestParam("receive") String receive,
@RequestParam("title") String title,
@RequestParam("msg") String msg) ;
}
五、源代码地点
GitHub·地点
https://github.com/cicadasmile/husky-spring-cloud
GitEE·地点
https://gitee.com/cicadasmile/husky-spring-cloud