前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【大坑】iBase4J 架构研究建议 顶

【大坑】iBase4J 架构研究建议 顶

作者头像
linapex
发布2019-03-26 10:15:00
8010
发布2019-03-26 10:15:00
举报
文章被收录于专栏:区块链实战

将项目跑起来,有一些个人建议,仅供作者与使用者参考~

iBase4J从技术选型来看,是没问题的,流程都一样。

我将源码debug,通读了一下,发现一些问题。

1.作者可能还没从单体应用转换为SOA服务化的思维。

文件:iBase4J-Biz-Web/src/main/resources/Spring-config.xml 中 <!-- dubbo --> <dubbo:reference id="sysProvider" interface="org.ibase4j.provider.ISysProvider" check="false" /> <dubbo:reference id="bizProvider" interface="org.ibase4j.provider.IBizProvider" check="false" />代码里dubbo的注册服务只有这两个,实际在 dubbo 里有多少个呢?只有一个。

这就导致了,dubbo无法管理这些服务,无法对服务进行限流,负载均衡,权重调节等等。

代码里,作者是怎么实现的呢?

查看源代码LoginController.java可知,通过,Parameter对象,传入service参数,method方法名,再通过,BaseProvider接口执行execute方法,找到service对应的service实现类,再找到方法,根据Parameter对象传入的Map或Bean,并去执行此方法。

``` provider.execute(new Parameter("sysUserService", "update").setModel(sysUser)); ```

严重性:极高 缺点:      客户端必须要知道接口名。      客户端必须要知道有哪些参数。      dubbo无法很好的进行服务治理,负载均衡等等。

建议:     1.将所有服务化暴露给duboo.     2.服务化可以在ctrl层直接调用.     3.封装api层,model层给客户端。 2.在service中,Map与Bean混用。

如SysUserService类中: ```     @Cacheable     public Long queryUserIdByThirdParty(ThirdPartyUser param) {         return thirdpartyMapper.queryUserIdByThirdParty(param.getProvider(), param.getOpenid());     } ``` ``` public Page<SysUser> query(Map<String, Object> params) {         Map<String, String> userTypeMap = sysDicService.queryDicByType("USERTYPE");         Page<SysUser> pageInfo = super.query(params);         for (SysUser userBean : pageInfo.getRecords()) {             if (userBean.getUserType() != null) {                 userBean.setUserTypeText(userTypeMap.get(userBean.getUserType().toString()));             }             if (userBean.getDeptId() != null) {                 SysDept sysDept = sysDeptService.queryById(userBean.getDeptId());                 if (sysDept != null) {                     userBean.setDeptName(sysDept.getDeptName());                 }             }             List<String> permissions = sysAuthorizeService.queryUserPermission(userBean.getId());             for (String permission : permissions) {                 if (StringUtils.isBlank(userBean.getPermission())) {                     userBean.setPermission(permission);                 } else {                     userBean.setPermission(userBean.getPermission() + ";" + permission);                 }             }         }         return pageInfo;     } ``` 根据阿里巴巴 Java 开发手册1.1.1 来看,不建议这样做,2个以上的参数,最好封装成查询Bean。

3.对于Redis缓存使用有点原始,数据字典处理有点原始。

如SysUserService类中,对于字典的文本读取转换: ``` public Page<SysUser> query(Map<String, Object> params) {         Map<String, String> userTypeMap = sysDicService.queryDicByType("USERTYPE");         Page<SysUser> pageInfo = super.query(params);         for (SysUser userBean : pageInfo.getRecords()) {             if (userBean.getUserType() != null) {                 userBean.setUserTypeText(userTypeMap.get(userBean.getUserType().toString()));             }             if (userBean.getDeptId() != null) {                 SysDept sysDept = sysDeptService.queryById(userBean.getDeptId());                 if (sysDept != null) {                     userBean.setDeptName(sysDept.getDeptName());                 }             }             List<String> permissions = sysAuthorizeService.queryUserPermission(userBean.getId());             for (String permission : permissions) {                 if (StringUtils.isBlank(userBean.getPermission())) {                     userBean.setPermission(permission);                 } else {                     userBean.setPermission(userBean.getPermission() + ";" + permission);                 }             }         }         return pageInfo;     } ```

如LoginController类中,对于缓存: ``` String password = (String)CacheUtil.getCache().get("LOGIN_" + user.getAccount());         if (StringUtils.isNotBlank(password)) {             if (user.getPassword().equals(password)) {                 WebUtil.saveCurrentUser(request, user.getAccount());                 success = true;             }         } ``` 如BaseService类中,对于缓存: ``` @Transactional     @SuppressWarnings("unchecked")     public T queryById(Long id) {         String key = getCacheKey(id);         T record = (T) CacheUtil.getCache().get(key);         if (record == null) {             String lockKey = getLockKey(id);             if (CacheUtil.getLock(lockKey)) {                 try {                     record = mapper.selectById(id);                     CacheUtil.getCache().set(key, record);                 } finally {                     CacheUtil.unlock(lockKey);                 }             } else {                 logger.debug(getClass().getSimpleName() + ":" + id + " retry queryById.");                 sleep(20);                 return queryById(id);             }         }         return record;     } ```

4.手动事务控制与Service的异常处理 如BaseService中: ``` 大量出现 @Transactional ```

```  @Transactional     public void delete(Long id) {         try {             mapper.deleteById(id);             CacheUtil.getCache().del(getCacheKey(id));         } catch (Exception e) {             throw new RuntimeException(e.getMessage(), e);         }     } ``` ```     @Transactional     public void del(Long id, Long userId) {         try {             T record = this.queryById(id);             record.setEnable(0);             record.setUpdateTime(new Date());             record.setUpdateBy(userId);             mapper.updateById(record);             CacheUtil.getCache().set(getCacheKey(id), record);         } catch (Exception e) {             throw new RuntimeException(e.getMessage(), e);         }     } ```

5.一不小心就被坑的机制

如BaseService中: ```   @Transactional     public T update(T record) {         try {             record.setUpdateTime(new Date());             if (record.getId() == null) {                 record.setCreateTime(new Date());                 mapper.insert(record);             } else {                 T org = this.queryById(record.getId());                 String lockKey = getLockKey(record.getId());                 if (CacheUtil.getLock(lockKey)) {                     try {                         T update = InstanceUtil.getDiff(org, record);                         update.setId(record.getId());                         mapper.updateById(update);                         record = mapper.selectById(record.getId());                         CacheUtil.getCache().set(getCacheKey(record.getId()), record);                     } finally {                         CacheUtil.unlock(lockKey);                     }                 } else {                     sleep(20);                     return update(record);                 }             }         } catch (DuplicateKeyException e) {             String msg = ExceptionUtil.getStackTraceAsString(e);             logger.error(Constants.Exception_Head + msg, e);             throw new RuntimeException("已经存在相同的配置.");         } catch (Exception e) {             String msg = ExceptionUtil.getStackTraceAsString(e);             logger.error(Constants.Exception_Head + msg, e);             throw new RuntimeException(msg);         }         return record;     } ``` 高并发情况下的锁与无限循环

其他的我后面再补充

(adsbygoogle = window.adsbygoogle || []).push({});

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017/05/10 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
负载均衡
负载均衡(Cloud Load Balancer,CLB)提供安全快捷的四七层流量分发服务,访问流量经由 CLB 可以自动分配到多台后端服务器上,扩展系统的服务能力并消除单点故障。轻松应对大流量访问场景。 网关负载均衡(Gateway Load Balancer,GWLB)是运行在网络层的负载均衡。通过 GWLB 可以帮助客户部署、扩展和管理第三方虚拟设备,操作简单,安全性强。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档