前言

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

浅谈分布式架构

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

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

单系统



对于一个刚起步的创业公司项目肯定是追求越快完成功能越好,并且用户量也不大。

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

垂直拆分-多应用



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

SOA服务化

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

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

等系统。

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

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

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

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

基于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。

登陆界面如下图:

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

消费服务

为了能够更直观的体验到消费服务,我新建了一个项目:

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配置文件时的路径一致:

    <!-- 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));
} }



消费者



提供者

可以看到确实是调用成功了的。

接下来将消费者项目也同时启动在来观察管理控制台有什么不一样:



会看到多了一个消费者所提供的服务com.crossoverjie.consumer.api.SalaryInfoApi,同时

com.crossoverJie.api.UserInfoApi服务已经正常,说明已经有消费者了。



点进去便可查看具体的消费者。

总结

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

再提一点:

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

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

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

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

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

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

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

基于 dubbo 的分布式架构的更多相关文章

  1. 基于dubbo的分布式项目实例应用

    本文主要学习dubbo服务的启动检查.集群容错.服务均衡.线程模型.直连提供者.只定阅.只注册等知识点,希望通过实例演示进一步理解和掌握这些知识点. 启动检查 Dubbo缺省会在启动消费者时检查依赖的 ...

  2. 基于Dubbo的分布式事务框架(LCN)

    原文地址:http://原文地址:https://github.com/1991wangliang/transaction 基于Dubbo的分布式事务框架(LCN) 该框架依赖Redis/dubbo/ ...

  3. 基于dubbo构建分布式项目与服务模块

      关于分布式服务架构的背景和需求可查阅http://dubbo.io/.不同于传统的单工程项目,本文主要学习如何通过maven和dubbo将构建分布项目以及服务模块,下面直接开始. 创建项目以及模块 ...

  4. 基于springCloud的分布式架构体系

    Spring Cloud作为一套微服务治理的框架,几乎考虑到了微服务治理的方方面面,之前也写过一些关于Spring Cloud文章,主要偏重各组件的使用,本次分享主要解答这两个问题:Spring Cl ...

  5. Dubbo入门到精通学习笔记(七):基于Dubbo的分布式系统架构介绍(以第三方支付系统架构为例)、消息中间件的作用介绍

    文章目录 架构简单介绍 消息中间件在分布式系统中的作用介绍 消息中间件的定义 消息中间件的作用 应用场景 JMS(Java Message Service) JMS消息模型 实现了JMS规范的消息中间 ...

  6. 基于Dubbo框架构建分布式服务(一)

    Dubbo是Alibaba开源的分布式服务框架,我们可以非常容易地通过Dubbo来构建分布式服务,并根据自己实际业务应用场景来选择合适的集群容错模式,这个对于很多应用都是迫切希望的,只需要通过简单的配 ...

  7. 基于Dubbo框架构建分布式服务

    Dubbo是Alibaba开源的分布式服务框架,我们可以非常容易地通过Dubbo来构建分布式服务,并根据自己实际业务应用场景来选择合适的集群容错模式,这个对于很多应用都是迫切希望的,只需要通过简单的配 ...

  8. [转载] 基于Dubbo框架构建分布式服务

    转载自http://shiyanjun.cn/archives/1075.html Dubbo是Alibaba开源的分布式服务框架,我们可以非常容易地通过Dubbo来构建分布式服务,并根据自己实际业务 ...

  9. Dubbo框架应用之(四)--Dubbo基于Zookeeper实现分布式实例

    上三篇文章主要是解决了概念性的补充和学习,充分结合实战来深入理解 入门实例解析 第一:provider-提供服务和相应的接口 创建DemoService接口 package com.unj.dubbo ...

随机推荐

  1. python第七天(字符编码,字符与字节,文件操作)

    一.字符编码: 定义:将人识别的字符转换成计算机能识别的0和1,转换的规则就是字符编码表. 常见编码表:ascii.unicode.GBK 编码表: 1.采用的都是unicode编码表 2.unico ...

  2. 网络攻击技术:SQL Injection(sql注入)

    网络攻击技术开篇——SQL Injection   1.1.1 摘要 日前,国内最大的程序员社区CSDN网站的用户数据库被黑客公开发布,600万用户的登录名及密码被公开泄露,随后又有多家网站的用户密码 ...

  3. C#实现 单点登录(SSO)

    SSO的基本概念 SSO英文全称Single Sign On(单点登录).SSO是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统.它包括可以将这次主要的登录映射到其他应用中用于同 ...

  4. Metasploit中aggregator插件无法使用

    Metasploit中aggregator插件无法使用   aggregator是Metasploit自带的一个插件,用来管理会话Session.该插件使用metasploit-aggreator库. ...

  5. WinCC OA基本概念

    WinCC OA 是一个模块化软件架构的系统.所需的功能由不同任务创建的特定单元处理.在WinCC OA中,这些单元称为管理器 - 管理器是软件自身的一些独立的处理过程. 图:WinCC OA系统由功 ...

  6. 第k个素因子只有3 5 7 的数

    题目描述 有一些数的素因子只有3.5.7,请设计一个算法,找出其中的第k个数. 给定一个数int k,请返回第k个数.保证k小于等于100. 测试样例: 3 返回:7 int findKth(int ...

  7. Javascript 标识符及同名标识符的优先级

    一.定义 标识符(Identifier)就是一个名字,用来对变量.函数.属性.参数进行命名,或者用做某些循环语句中的跳转位置的标记. //变量 var Identifier = 123; //属性 ( ...

  8. 马昕璐 201771010118《面向对象程序设计(java)》第十八周学习总结

    实验十八  总复习 实验时间 2018-12-30 1.实验目的与要求 (1) 综合掌握java基本程序结构: (2) 综合掌握java面向对象程序设计特点: (3) 综合掌握java GUI 程序设 ...

  9. DP-01背包

    题目传送门 题目类似01背包,但存在一个选取先后不同价值会有损耗,所有对物品按易损耗的程度从大到小排个序来顺序选取. #include<bits/stdc++.h> using names ...

  10. 详解 vue-cli 的打包配置文件代码(给大家写写注释)

    一.前言 对于webpack基础不好,node指令不通的童鞋.估计对自己搭建Vue.react脚手架是相当头疼的,有种无从下手的感觉.然而,从头看这2块,耗时太长,而且说实话得练才行,不练练手看不明白 ...