文档章节

SSM(十一) 基于dubbo的分布式架构

crossoverJie
 crossoverJie
发布于 2017/04/08 00:47
字数 2037
阅读 5126
收藏 406

dubbo.jpg

前言

现在越来越多的互联网公司还是将自己公司的项目进行服务化,这确实是今后项目开发的一个趋势,就这个点再凭借之前的SSM项目来让第一次接触的同学能快速上手。

浅谈分布式架构

分布式架构单看这个名字给人的感觉就是高逼格,但其实从历史的角度来分析一下就比较明了了。

我们拿一个电商系统来说:

单系统

E65B5547-AF84-4D31-836D-72892C7AC7EA.png 对于一个刚起步的创业公司项目肯定是追求越快完成功能越好,并且用户量也不大。

这时候所有的业务逻辑都是在一个项目中就可以满足。

垂直拆分-多应用

QQ20170406-230056@2x.jpg 当业务量和用户量发展到一定地步的时候,这时一般会将应用同时部署到几台服务器上,在用户访问的时候使用Nginx进行反向代理和简单的负载均衡。

SOA服务化

当整个系统以及发展的足够大的时候,比如一个电商系统中存在有:

  • 用户系统
  • 订单系统
  • 支付系统
  • 物流系统

等系统。 如果每次修改了其中一个系统就要重新发布上线的话那么耦合就太严重了。

所以需要将整个项目拆分成若干个独立的应用,可以进行独立的开发上线实现快速迭代。

dubbo.png

如上图所示每个应用之间相互独立,每个应用可以消费其他应用暴露出来的服务,同时也对外提供服务。

从架构的层面简单的理解了,接下来看看如何编码实现。

基于dubbo的实现

dubbo应该算是国内使用最多的分布式服务框架,基于此来实现对新入门的同学应该很有帮助。

其中有涉及到安装dubbo服务的注册中心zookeeper等相关知识点可以自行查看官方文档,这里就不单独讲了。

对外提供服务

首先第一步需要在SSM-API模块中定义一个接口,这里就搞了一个用户查询的接口

/**
 * Function:用户API
 * @author chenjiec
 * Date: 2017/4/4 下午9:46
 * @since JDK 1.7
 */
public interface UserInfoApi {

    /**
     * 获取用户信息
     * @param userId
     * @return
     * @throws Exception
     */
    public UserInfoRsp getUserInfo(int userId) throws Exception;
}

接着在SSM-SERVICE模块中进行实现:

import com.alibaba.dubbo.config.annotation.Service;
/**
 * Function:
 * @author chenjiec
 * Date: 2017/4/4 下午9:51
 * @since JDK 1.7
 */
@Service
public class UserInfoApiImpl implements UserInfoApi {
    private static Logger logger = LoggerFactory.getLogger(UserInfoApiImpl.class);

    @Autowired
    private T_userService t_userService ;

    /**
     * 获取用户信息
     *
     * @param userId
     * @return
     * @throws Exception
     */
    @Override
    public UserInfoRsp getUserInfo(int userId) throws Exception {
        logger.info("用户查询Id="+userId);

        //返回对象
        UserInfoRsp userInfoRsp = new UserInfoRsp() ;
        T_user t_user = t_userService.selectByPrimaryKey(userId) ;

        //构建
        buildUserInfoRsp(userInfoRsp,t_user) ;

        return userInfoRsp;
    }


    /**
     * 构建返回
     * @param userInfoRsp
     * @param t_user
     */
    private void buildUserInfoRsp(UserInfoRsp userInfoRsp, T_user t_user) {
        if (t_user ==  null){
            t_user = new T_user() ;
        }
        CommonUtil.setLogValueModelToModel(t_user,userInfoRsp);
    }
}

这些都是通用的代码,但值得注意的一点是这里使用的dubbo框架所提供的@service注解。作用是声明需要暴露的服务接口。

再之后就是几个dubbo相关的配置文件了。

spring-dubbo-config.xml

	<dubbo:application name="ssm-service" owner="crossoverJie"
		organization="ssm-crossoverJie" logger="slf4j"/>

	<dubbo:registry id="dubbo-registry" address="zookeeper://192.168.0.188:2181"
		file="/tmp/dubbo.cachr" />

	<dubbo:monitor protocol="registry" />

	<dubbo:protocol name="dubbo" port="20880" />

	<dubbo:provider timeout="15000" retries="0" delay="-1" />

	<dubbo:consumer check="false" timeout="15000" />

其实就是配置我们服务注册的zk地址,以及服务名称、超时时间等配置。

spring-dubbo-provider.xml

<dubbo:annotation package="com.crossoverJie.api.impl" />

这个配置扫描注解包的位置,一般配置到接口实现包即可。

spring-dubbo-consumer.xml

这个是消费者配置项,表明我们需要依赖的其他应用。 这里我们在SSM-BOOT项目中进行配置:

<dubbo:reference id="userInfoApi"
		interface="com.crossoverJie.api.UserInfoApi" />

直接就是配置的刚才我们提供的那个用户查询的接口,这样当我们自己的内部项目需要使用到这个服务只需要依赖SSM-BOOT即可,不需要单独的再去配置consumer。这个我有在上一篇SSM(十) 项目重构-互联网项目的Maven结构中也有提到。

安装管理控制台

还有一个需要做的就是安装管理控制台,这里可以看到我们有多少服务、调用情况是怎么样等作用。

这里我们可以将dubbo的官方源码下载下来,对其中的dubbo-admin模块进行打包,将生成的WAR包放到Tomcat中运行起来即可。

但是需要注意一点的是: 需要将其中的dubbo.properties的zk地址修改为自己的即可。

dubbo.registry.address=zookeeper://127.0.0.1:2181
dubbo.admin.root.password=root
dubbo.admin.guest.password=guest

到时候登陆的话使用root,密码也是root。 使用guest,密码也是guest。

登陆界面如下图: QQ20170407-001924@2x.jpg

其中我们可以看到有两个服务以及注册上去了,但是没有消费者。

消费服务

为了能够更直观的体验到消费服务,我新建了一个项目: https://github.com/crossoverJie/SSM-CONSUMER

其中在SSM-CONSUMER-API中我也定义了一个接口:

/**
 * Function:薪资API
 * @author chenjiec
 * Date: 2017/4/4 下午9:46
 * @since JDK 1.7
 */
public interface SalaryInfoApi {

    /**
     * 获取薪资
     * @param userId
     * @return
     * @throws Exception
     */
    public SalaryInfoRsp getSalaryInfo(int userId) throws Exception;
}

因为作为消费者的同时我们也对外提供了一个获取薪资的一个服务。

SSM-CONSUMER-SERVICE模块中进行了实现:

/**
 * Function:
 * @author chenjiec
 * Date: 2017/4/4 下午9:51
 * @since JDK 1.7
 */
@Service
public class SalaryInfoApiImpl implements SalaryInfoApi {
    private static Logger logger = LoggerFactory.getLogger(SalaryInfoApiImpl.class);

    @Autowired
    UserInfoApi userInfoApi ;

    /**
     * 获取用户信息
     *
     * @param userId
     * @return
     * @throws Exception
     */
    @Override
    public SalaryInfoRsp getSalaryInfo(int userId) throws Exception {
        logger.info("薪资查询Id="+userId);

        //返回对象
        SalaryInfoRsp salaryInfoRsp = new SalaryInfoRsp() ;
        
        //调用远程服务
        UserInfoRsp userInfo = userInfoApi.getUserInfo(userId);
        
        salaryInfoRsp.setUsername(userInfo.getUserName());

        return salaryInfoRsp;
    }


}

其中就可以直接使用userInfoApi调用之前的个人信息服务。

再调用之前需要注意的有点是,我们只需要依赖SSM-BOOT这个模块即可进行调用,因为SSM-BOOT模块已经为我们配置了消费者之类的操作了:

        <dependency>
            <groupId>com.crossoverJie</groupId>
            <artifactId>SSM-BOOT</artifactId>
        </dependency>

还有一点是在配置SSM-BOOT中的spring-dubbo-cosumer.xml配置文件的时候,路径要和我们初始化spring配置文件时的路径一致: QQ20170407-005850@2x.jpg

    <!-- Spring和mybatis的配置文件 -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath*:spring/*.xml</param-value>
    </context-param>

接下来跑个单测试一下能否调通:

/**
 * Function:
 *
 * @author chenjiec
 *         Date: 2017/4/5 下午10:41
 * @since JDK 1.7
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath*:/spring/*.xml" })
public class SalaryInfoApiImplTest {

    @Autowired
    private SalaryInfoApi salaryInfoApi ;

    @Test
    public void getSalaryInfo() throws Exception {
        SalaryInfoRsp salaryInfo = salaryInfoApi.getSalaryInfo(1);
        System.out.println(JSON.toJSONString(salaryInfo));
    }

}

消费者.jpg 消费者

提供者.jpg 提供者 可以看到确实是调用成功了的。

接下来将消费者项目也同时启动在来观察管理控制台有什么不一样: QQ20170407-003413@2x.jpg 会看到多了一个消费者所提供的服务com.crossoverjie.consumer.api.SalaryInfoApi,同时 com.crossoverJie.api.UserInfoApi服务已经正常,说明已经有消费者了。

QQ20170407-003456@2x.jpg 点进去便可查看具体的消费者。

总结

这样一个基于dubbo的分布式服务已经讲的差不多了,在实际的开发中我们便会开发一个大系统中的某一个子应用,这样就算一个子应用出问题了也不会影响到整个大的项目。

再提一点: 在实际的生产环境一般同一个服务我们都会有一个master,slave的主从服务,这样在上线的过程中不至于整个应用出现无法使用的尴尬情况。

谈到了SOA的好处,那么自然也有相对于传统模式的不方便之处:

  • 拆分一个大的项目为成百上千的子应用就不可能手动上线了,即需要自动化的部署上线,如Jenkins
  • 还有一个需要做到的就是监控,需要一个单独的监控平台来帮我们实时查看各个服务的运行情况以便于及时定位和解决问题。
  • 日志查看分析,拆分之后不可能再去每台服务器上查看日志,需要一个单独的日志查看分析工具如elk

以上就是我理解的,如有差错欢迎指正。

项目地址:https://github.com/crossoverJie/SSM.git

个人博客地址:http://crossoverjie.top

GitHub地址:https://github.com/crossoverJie

© 著作权归作者所有

crossoverJie

crossoverJie

粉丝 676
博文 90
码字总数 174653
作品 0
江北
后端工程师
私信 提问
加载中

评论(11)

crossoverJie
crossoverJie

引用来自“Bonismo”的评论

github 上的项目没有 SSM-BOOT , 什么原因啊
有的哦 https://github.com/crossoverJie/SSM/tree/master/SSM-BOOT
Bonismo
Bonismo
github 上的项目没有 SSM-BOOT , 什么原因啊
crossoverJie
crossoverJie

引用来自“阿cat”的评论

spring cloud很难吗?
不难啊 只是目前国内文档和案例相对较少 需要自己踩坑 我现在正在做的一个项目就是springcloud 感觉用起还不错
MGL_TECH
MGL_TECH
spring cloud很难吗?
z
zhanghengtwo
crossoverJie
crossoverJie

引用来自“KevinLi1230”的评论

理解的很不错,我们公司大致就是这样子,唯独欠缺的就是集中到日志预警分析平台,缺乏像elk这类的日志分析平台
😌 是的 有一个日志查看平台查看线上日志很方便 elk搭配pinpoint这样的监控平台定位问题非常快。
KevinLi1230
KevinLi1230
理解的很不错,我们公司大致就是这样子,唯独欠缺的就是集中到日志预警分析平台,缺乏像elk这类的日志分析平台
OSC_IeJyRJ
OSC_IeJyRJ
谢谢楼主分享,受益匪浅
crossoverJie
crossoverJie

引用来自“漆黑的烈焰使”的评论

好几张图片挂了
好了。
开源中国首席罗纳尔多
开源中国首席罗纳尔多
好几张图片挂了
crossoverJie/SSM

使用Idea搭建的Maven项目,会不定期更新一些在实际开发中使用的技巧,没有复杂的业务流程,更不是XXXX系统,只有一些技术的分享 目录结构 ├── SSM-API // 通用API │ ├── src/main│ ├...

crossoverJie
2018/05/09
0
0
推荐几个自己写的Java后端相关的范例项目(转载)

http://wosyingjun.iteye.com/blog/2312553 这里推荐几个自己写的范例项目,主要采用SSM(Spring+SpringMVC+Mybatis)框架,分布式架构采用的是(dubbo+zookeeper)。范例项目的好处是简单易...

指尖的舞者
2016/09/27
147
0
SSM(十一) 基于 dubbo 的分布式架构

前言 现在越来越多的互联网公司还是将自己公司的项目进行服务化,这确实是今后项目开发的一个趋势,就这个点再凭借之前的项目来让第一次接触的同学能快速上手。 浅谈分布式架构 单看这个名字...

crossoverJie
2017/04/07
0
0
ZHENFENGSHISAN/perfect-ssm

Quick Start 项目简介 ssm系列 ssm-demo:Spring+SpringMVC+Mybatis+easyUI整合 perfect-ssm:RESTful API+redis缓存 ssm-cluster:前后端分离+集群部署 ssm-dubbo:dubbo服务化 ssm-micro-se......

ZHENFENGSHISAN
2017/09/18
0
0
基于 dubbo 的分布式架构

前言 现在越来越多的互联网公司还是将自己公司的项目进行服务化,这确实是今后项目开发的一个趋势,就这个点再凭借之前的 SSM 项目来让第一次接触的同学能快速上手。 浅谈分布式架构 分布式架...

Java小铺
2018/07/06
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Android双向绑定原理简述

Android双向绑定原理简述 双向绑定涉及两个部分,即将业务状态的变化传递给UI,以及将用户输入信息传递给业务模型。 首先我们来看业务状态是如何传递给UI的。开启dataBinding后,编译器为布局...

tommwq
今天
4
0
Spring系列教程八: Spring实现事务的两种方式

一、 Spring事务概念: 事务是一系列的动作,它们综合在一起才是一个完整的工作单元,这些动作必须全部完成,如果有一个失败的话,那么事务就会回滚到最开始的状态,仿佛什么都没发生过一样。...

我叫小糖主
今天
8
0
CentOS 的基本使用

1. 使用 sudo 命令, 可以以 root 身份执行命令, 必须要在 /etc/sudoers 中定义普通用户 2. 设置 阿里云 yum 镜像, 参考 https://opsx.alibaba.com/mirror # 备份mv /etc/yum.repos.d/CentO...

北漂的我
昨天
5
0
Proxmox VE技巧 移除PVE “没有有效订阅” 的弹窗提示

登陆的时候提示没有有效的订阅You do not have a valid subscription for this server. Please visit www.proxmox.com to get a list of available options. 用的是免费版的,所以每次都提示......

以谁为师
昨天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部