背景

随着互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构以及流动计算架构势在必行,亟需一个治理系统确保架构有条不紊的演进。

单一应用架构

当网站流量很小时,只需一个应用,将所有功能都部署在一起,以减少部署节点和成本。此时,用于简化增删改查工作量的数据访问框架(ORM)是关键。

  • Dubbo是Alibaba开源的分布式服务框架,它最大的特点是按照分层的方式来架构,使用这种方式可以使各个层之间解耦合(或者最大限度地松耦合)。从服务模型的角度来看,Dubbo采用的是一种非常简单的模型,要么是提供方提供服务,要么是消费方消费服务,所以基于这一点可以抽象出服务提供方(Provider)和服务消费方(Consumer)两个角色。关于注册中心、协议支持、服务监控等内容
  • Zookeeper 分布式服务框架是 Apache Hadoop 的一个子项目,它主要是用来解决分布式应用中经常遇到的一些数据管理问题,如:统一命名服务、状态同步服务、集群管理、分布式应用配置项的管理等

  使用案例:

             先前由于业务需求,要出很多新的功能,考虑到服务器的压力(用户正常访问的业务+不断迭代的新功能明显感觉得到系统缓慢,响应延迟),单一的webservice或者httpclient互相调用不同的服务也感觉比较笨拙,加上某个提供者挂掉导致部分业务不能正常访问,所以就有采用了dubbo框架作为不同的服务之间相互调用。                  

-----------------------------------------------------------------分割线--------------------------------------------------------------

  • 整合dubbo之前我先贴上几段spring代码(如何搭建dubbo和Zookeeper环境这里就不介绍了,网上有很多教程, 我的dubbo版本是2.5.4,zookeeper是3.3.6),主要是模拟spring mvc的一个简单过程,但是没用到数据库和spring 事务等, 用来对比dubbo和spring整合后到底哪里发生了改变
  1.   首先是实体类,我们经常说的pojo
package com.zdd.dubbo.provider;

/**
*
* @ClassName: Goods
* @Description: 商品表
* @author: kevin
* @date: 2016-10-21 上午10:23:03
*/
public class Goods { private int id;
private String name;
private double price;
private int num;
private String color;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
} @Override
public String toString() {
return "Goods [id=" + id + ", name=" + name + ", price=" + price
+ ", num=" + num + ", color=" + color + "]";
} }

   
查询商品接口以及实现类

package com.zdd.dubbo.provider;

import java.util.List;

public interface GoodsService {

    List<Goods> findAllGoodsByParams();
}
package com.zdd.dubbo.provider;

import java.util.ArrayList;
import java.util.List; /**
*
* @ClassName: GoodsServiceImpl
* @Description: 实现类,模拟从数据库查出数据
* @author: kevin
* @date: 2016-10-21 上午10:28:36
*/
public class GoodsServiceImpl implements GoodsService { @Override
public List<Goods> findAllGoodsByParams() { List<Goods> glist = new ArrayList<>(); Goods g = new Goods();
g.setColor("蓝色");
g.setId(1);
g.setName("耐克长袖");
g.setPrice(268);
Goods g1 = new Goods();
g1.setColor("黑色");
g1.setId(1);
g1.setName("阿迪达斯板鞋");
g1.setPrice(499);
glist.add(g);
glist.add(g1);
return glist;
} }

控制层代码,在springmvc又称handler

package com.zdd.dubbo.consumer;

import javax.xml.bind.annotation.XmlAccessOrder;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; import com.zdd.dubbo.provider.GoodsService; public class GoodsAction { private static GoodsService goodsService; /**
*
* @Title: main
* @Description: 模拟spring mvc的 请求 类似于 @Controller
* @param args
* @return: void
*/
public static void main(String[] args) {
//spring 注入
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("file:D:/workspace/GZDTL_TRUNK/zdd-web-consumer/spring/applicationContext.xml");
goodsService = (GoodsService) applicationContext.getBean("getGoodService");
System.out.println(goodsService.findAllGoodsByParams()); }
}

spring的配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
">
<!-- <import resource="dubbo-provider.xml"></import> -->
<!-- spring注入 -->
<bean id="getGoodService" class="com.zdd.dubbo.provider.GoodsServiceImpl"></bean>
</beans>

通过spring注入然后执行main方法调用本地的service获取一个商品list,输出结果如下图。


#这时候我打算用dubbo框架改变上面的代码,通过dubbo把需要提供的服务暴露出去,然后消费者再进行调用,使得2个系统之间耦合度变低,我的理解是消费者只关心他要调用什么服务,提供者只关心他提供什么服务, 它们之间通过rpc协议来进行传输。因为当垂直应用越来越多,应用之间交互不可避免,将核心业务抽取出来,作为独立的服务,逐渐形成稳定的服务中心,使前端应用能更快速的响应多变的市场需求。此时,用于提高业务复用及整合的分布式服务框架(RPC)是关键。

  • dubbo-provider.xml 提供者配置(注意:注册中心暴露服务地址是zookeeper的地址,例如你本地安装了zookeeper并启动成功,那么你的地址就是zookeeper://127.0.0.1:2181,必须要启动zookeeper,不然本地服务无法注册上去,无法注册的话就没办法实现远程调用)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
    xsi:schemaLocation="http://www.springframework.org/schema/beans        
    http://www.springframework.org/schema/beans/spring-beans.xsd        
    http://code.alibabatech.com/schema/dubbo        
    http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
 
    <!-- 提供方应用信息,用于计算依赖关系 -->
    <dubbo:application name="find_all_goods"  />
 
    <!-- 使用multicast广播注册中心暴露服务地址 -->
   <!--  <dubbo:registry address="multicast://224.5.6.7:1234" /> -->
 
     <!-- 使用zookeeper注册中心暴露服务地址 -->
    <dubbo:registry address="zookeeper://xx.xxxx.xx:2181" />
 
    <!-- 用dubbo协议在20880端口暴露服务 -->
    <dubbo:protocol name="dubbo" port="20880" />
 
    <!-- 声明需要暴露的服务接口(注意是接口,不是实现类) -->
    <dubbo:service interface="com.zdd.dubbo.provider.GoodsService" ref="goodsService" />
    
    <!-- 这里是具体实现类,id和上面的暴露的服务接口ref要一致,dubbo就是通过这个来注册对应的服务 -->
    <bean id="goodsService" class="com.zdd.dubbo.provider.GoodsServiceImpl"></bean>
    
</beans>
  • consumer.xml 消费者的xml配置(注意:对比上面的提供者xml配置可以清楚的发现消费者通过 <dubbo:reference id id="goodsService"> 标签指向了 goodsService, 假设我们随便写一个mallService 肯定是不行的,因为我们提供的只有goodService服务)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<!-- 消费方应用名,用于计算依赖关系,不是匹配条件,不要与提供方一样 -->
<dubbo:application name="dubbo-consumer"/>
<!-- 使用multicast广播注册中心暴露发现服务地址 -->
<!-- <dubbo:registry address="multicast://224.5.6.7:1234" /> -->
<dubbo:registry address="zookeeper://xxx.xx.xx:2181" />
<!-- 生成远程服务代理,可以和本地bean一样调用 -->
<dubbo:reference id="goodsService" interface="com.zdd.dubbo.provider.GoodsService" />
</beans>
  • 最后整合完测试一下代码 (注意:这段代码先初始化的是提供者的xml,然后初始化消费者的xml。必须按顺序执行,否则的话服务提供的都没起来,消费方是拿不到zk上面的服务的)

    package com.zdd.dubbo.consumer;
    
    import java.io.IOException;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext; import com.zdd.dubbo.provider.GoodsService; public class GoodsAction {
    private static GoodsService goodsService; /**
    *
    * @Title: main
    * @Description: 模拟spring mvc的 请求 类似于 @Controller
    * @param args
    * @return: void
    * @throws IOException
    */
    public static void main(String[] args) throws IOException {
    /*//spring 注入
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("file:D:/workspace/GZDTL_TRUNK/zdd-web-consumer/spring/applicationContext.xml");
    goodsService = (GoodsService) applicationContext.getBean("getGoodService");
    System.out.println(goodsService.findAllGoodsByParams());*/
    ApplicationContext dubbo_provider = new ClassPathXmlApplicationContext("file:D:/workspace/GZDTL_TRUNK/zdd-service-provider/spring_dubbo/dubbo-provider.xml");
    ApplicationContext dubbo_cusumer = new ClassPathXmlApplicationContext("file:D:/workspace/GZDTL_TRUNK/zdd-web-consumer/spring/dubbo-consumer.xml");
    GoodsService service = (GoodsService) dubbo_cusumer.getBean("goodsService");
    System.out.println(service.findAllGoodsByParams());
    System.in.read();
    }
    }

    dubbo main 方法

  • 输出结果如下。

【原】Spring和Dubbo基于XML配置整合过程的更多相关文章

  1. 一步一步深入spring(6)--使用基于XML配置的spring实现的AOP

    上节我们提到了使用基于注解实现的AOP,这节我们将用基于xml配置的方式来实现的AOP. 1.首先建立一个类,作为切面类,这个类主要用来实现注解中各种通知要实现的方法. package com.yan ...

  2. ssm整合(基于xml配置方式)

    本文是基于xml配置的方式来整合SpringMVC.Spring和Mybatis(基于注解的方式会再写一篇文章),步骤如下: (1)首先自然是依赖包的配置文件 pom.xml <project ...

  3. Spring学习之旅(七)基于XML配置与基于AspectJ注解配置的AOP编程比较

    本篇博文用一个稍复杂点的案例来对比一下基于XML配置与基于AspectJ注解配置的AOP编程的不同. 相关引入包等Spring  AOP编程准备,请参考小编的其他博文,这里不再赘述. 案例要求: 写一 ...

  4. Unit03: Spring Web MVC简介 、 基于XML配置的MVC应用 、 基于注解配置的MVC应用

    Unit03: Spring Web MVC简介 . 基于XML配置的MVC应用 . 基于注解配置的MVC应用 springmvc (1)springmvc是什么? 是一个mvc框架,用来简化基于mv ...

  5. Spring Boot 框架下使用MyBatis访问数据库之基于XML配置的方式

    MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过程以及高级映射.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBatis 可以使用简单的 XML ...

  6. Spring Aop(七)——基于XML配置的Spring Aop

    转发:https://www.iteye.com/blog/elim-2396043 7 基于XML配置的Spring AOP 基于XML配置的Spring AOP需要引入AOP配置的Schema,然 ...

  7. 【Spring Framework】Spring入门教程(二)基于xml配置对象容器

    基于xml配置对象容器--xml 标签说明 alias标签 作用:为已配置的bean设置别名 --applicationContext.xml配置文件 <?xml version="1 ...

  8. Spring实战——无需一行xml配置实现自动化注入

    已经想不起来上一次买技术相关的书是什么时候了,一直以来都习惯性的下载一份电子档看看.显然,如果不是基于强烈的需求或强大的动力鞭策下,大部分的书籍也都只是蜻蜓点水,浮光掠影. 就像有位同事说的一样,有些 ...

  9. Spring装配Bean---使用xml配置

    声明Bean Spring配置文件的根元素是<beans>. 在<beans>元素内,你可以放所有的Spring配置信息,包括<bean>元素的声明. 除了Bean ...

随机推荐

  1. Java中的内部类(二)成员内部类

    Java中的成员内部类(实例内部类):相当于类中的一个成员变量,下面通过一个例子来观察成员内部类的特点 public class Outer { //定义一个实例变量和一个静态变量 private i ...

  2. 2018 OCP 052最新题库及答案-4

    4.For which requirement should you configure shared servers? A) accommodating an increasing number o ...

  3. AsyncTask的工作原理

    AsyncTask是Android本身提供的一种轻量级的异步任务类.它可以在线程池中执行后台任务,然后把执行的进度和最终的结果传递给主线程更新UI.实际上,AsyncTask内部是封装了Thread和 ...

  4. [Swift实际操作]八、实用进阶-(2)Swift语言中的三种消息传递模式

    本文将通过响应按钮的点击事件,来演示Target-Action消息传递机制,该机制主要用于响应用户的界面操作.打开创建的空白项目.然后在左侧的项目导航区,打开视图控制器的代码文件:ViewContro ...

  5. 考试题 T3

    题意分析 首先\(\%\%\%\%olinr\)以及花_Q\(julao\)当场切题 然后就是怎么求 \[max(|a-A|,|b-B|)=max(a-A,A-a,B-b,b-B)\] 我们令\(x_ ...

  6. Flink--Streaming Connectors

    原网址:https://ci.apache.org/projects/flink/flink-docs-release-1.7/dev/connectors/ Predefined Sources a ...

  7. STM32-RTC实时时钟-毫秒计时实现

    OS:Windows 64 Development kit:MDK5.14 IDE:UV4 MCU:STM32F103C8T6 1.RTC时钟简介 STM32 的实时时钟(RTC)是一个独立的定时器, ...

  8. Eigenface与PCA人脸识别算法实验

    简单的特征脸识别实验 实现特征脸的过程其实就是主成分分析(Principal Component Analysis,PCA)的一个过程.关于PCA的原理问题,它是一种数学降维的方法.是为了简化问题.在 ...

  9. MySql互为主从配置文件及配置方法

    # Example MySQL config file for medium systems. # # This is for a system with little memory (32M - 6 ...

  10. Hibernate中Query.list()方法报IllegalArgumentException异常

    最近在使用Hibernate开发项目,在写好hql语句,并初始化Query对象,执行Query.list()方法时,应用报IllegalArgumentException异常.经网上查询,现已经基本决 ...