更新进度(共6节):
01:项目技术选型简介,架构图解说明
02:业务架构设计,系统分层管理
03:数据库选型,业务数据设计规划
04:中间件集成,公共服务管理
中间件是基础软件的一类, 属于复用性极高的软件。处于操作系统软件与应用程序的之间。是一种独立的系统软件,也可以是公共的服务程序,分布式架构系统借助中间件,可以在不同的技术之间共享资源,或者不同的服务直接传递信息。中间件位操作系统之上,管理计算机资源和网络通讯。是连接两个独立应用程序或独立系统的软件,例如:
公共服务,顾名思义就是系统内通用的服务,例如用户身份验证,消息发送,监控预警,网关服务等。
该案例的中间件和公共服务,都是基于 Feign
接口统一的方式提供服务。
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); } }
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) ; } }
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); } }
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); } }
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) ; }
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