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

- 单一应用架构
当网站流量很小时,只需一个应用,将所有功能都部署在一起,以减少部署节点和成本。
此时,用于简化增删改查工作量的 数据访问框架(ORM) 是关键。
- 垂直应用架构
当访问量逐渐增大,单一应用增加机器带来的加速度越来越小,将应用拆成互不相干的几个应用,以提升效率。
此时,用于加速前端页面开发的 Web框架(MVC) 是关键。
- 分布式服务架构
当垂直应用越来越多,应用之间交互不可避免,将核心业务抽取出来
作为独立的服务,逐渐形成稳定的服务中心,使前端应用
能更快速的响应多变的市场需求。
此时,用于提高业务复用及整合的 分布式服务框架(RPC) 是关键。
- 流动计算架构
当服务越来越多,容量的评估,小服务资源的浪费等问题逐渐显现
此时需增加一个调度中心基于访问压力实时管理集群容量,提高集群利用率。
此时,用于提高机器利用率的 资源调度和治理中心(SOA) 是关键。
什么是Dubbo
Dubbo是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,SOA服务治理方案。
简单的说,dubbo就是个服务框架,如果没有分布式的需求,其实是不需要用的,只有在分布式的时候,
才有dubbo这样的分布式服务框架的需求,并且本质上是个服务调用,说白了就是个远程服务调用的分布式框架。
告别Web Service模式中的wsdl,以服务者与消费者的方式在dubbo 上注册)。
其核心部分包含:
1.远程通讯,提供对多种基于长连接的NiO框架抽象封装,包括多种线程模型,序列化,
以及“请求一响应”模式的信息交换方式。
2.集群容错: 提供基于接口方法的透明远程过程调用,包括多协议支持。以
及负载均衡,失败容错,地址路由,动态配置等集群支持。
3.自动发现:基于注册中心目录服务,使用服务消费能动态查找服务提供方,使地址透明,
使用服务提供方可以平滑增加或减少服务器
Dubbo能做什么
问题:
服务的URL管理非常困难(rmi://、http:*、)、F5负载均衡器的单点压力(硬件成本)
各个服务之间依赖管理非常复杂
各个服务之间如何进行监控
1.透明化的远程方法调用,就像调用本地方法一样调用远程方法,只需简单
配置,没有任何API侵入。
2.软负载均衡及容错机制,可在内网替代F5等硬件负鞭均衡器,降低成本,
减少单点。
3.服务自动注册与发现,不再需要写死服务提供方地址,注册中心基于楼口
名查询服务提供者的IP地址,并且能够平滑添加或删除服务提供者。
4.Dubbo采用全Spring 配置方式,功明化接入应用,对应用没有任何API侵
只需用Spring加载Dubbo的配置即可,Dubbo基FSpring的Schema扩
入,展进行加载。
节点角色说明:
Provider: 暴露服务的服务提供方。
Consumer: 调用远程服务的服务消费方。
Registry: 服务注册与发现的注册中心。
Monitor: 统计服务的调用次调和调用时间的监控中心。
登录小案例:
采用父子工程

依赖
<!--日志-->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.32</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.2.0.RELEASE</version>
</dependency>
<dependency>
<groupId>com.github.sgroschupf</groupId>
<artifactId>zkclient</artifactId>
<version>0.1</version>
</dependency>
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.10</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.5.3</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.2.0.RELEASE</version>
</dependency>
<!--MyBatis和Spring的整合包 由MyBatis提供-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.0</version>
</dependency>
<!--MyBatis的核心jar文件-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.1</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
Service子工程
entity
public class student implements Serializable {
private Integer stuid;
private String stuname;
private Integer age;
public Integer getStuid() {
return stuid;
}
public void setStuid(Integer stuid) {
this.stuid = stuid;
}
public String getStuname() {
return stuname;
}
public void setStuname(String stuname) {
this.stuname = stuname;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
service
public interface service {
public student stulogin(student stu);
}
Producers子工程
dao
@Repository
public interface stuLogin {
@Select("select * from student where stuname=#{stuname}")
public student stulogin(String stuname);
}
serviceimpl
@Service("service")
public class stuLoginimpl implements service {
@Resource
private stuLogin stuLogin;
@Override
public student stulogin(student stu) {
student stulogin = stuLogin.stulogin(stu.getStuname());
if(stulogin!=null){
if (stu.getAge().equals(stulogin.getAge())){
return stulogin;
}
}
return null;
}
}
applicationContext.xml
<?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" xmlns:mvc="http://www.springframework.org/schema/mvc"
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://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 导入数据库连接文件-->
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="ignoreUnresolvablePlaceholders" value="true" />
<property name="location" value="classpath:jdbc.properties"/>
</bean>
<!--配置数据源-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="password" value="${jdbc.password}"/>
<property name="username" value="${jdbc.user}"/>
</bean>
<!--配置MyBatis的核心对象SqlSessionFactoryBean-->
<bean id="SessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--创建包扫描器(借助dao接口实现动态代理)-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer ">
<property name="basePackage" value="com.MckzDubbo.dao"/>
</bean>
<context:component-scan base-package="com.MckzDubbo.*"/>
<context:annotation-config/>
<mvc:annotation-driven/>
<!-- 提供方应用信息,用于计算依赖关系 -->
<dubbo:application name="app-provider"/>
<!-- 使用zookeeper注册中心暴露服务地址 -->
<dubbo:registry address="127.0.0.1:2181" protocol="zookeeper" />
<!-- 用dubbo协议在20880端口暴露服务 -->
<dubbo:protocol name="dubbo" port="20880" />
<!-- 声明需要暴露的服务接口 -->
<dubbo:service interface="com.MckzDubbo.service.service" ref="service" />
</beans>
jdbc.properties
jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/student jdbc.user=root jdbc.password=123
log4j.properties
### direct log messages to stdout ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
### direct messages to file mylog.log ###
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=F:\\study\\IDEAY2\\smbms\\src\\main\\webapp\\WEB-INF\\log.txt
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
### set log levels - for more verbose logging change 'info' to 'debug' ###
log4j.rootLogger=debug, stdout,file
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<!--Spring和MyBatis整合的核心配置-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!--配置SpringMVC的核心控制器DispatcherServlet-->
<servlet>
<servlet-name>SpringMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:applicationContext.xml</param-value>
</init-param>
</servlet>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet-mapping>
<servlet-name>SpringMVC</servlet-name>
<!--设置映射路径,/代表所有的请求都会被核心控制器映射到对应的Controller中-->
<url-pattern>/</url-pattern>
</servlet-mapping>
<!--编码过滤器-->
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<!--初始化参数-->
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
Consumer子工程
Controller
@Controller
@RequestMapping("/student")
public class myController {
@Resource
private service stuservice;
@RequestMapping("/logins")
public ModelAndView one(student stu){
ModelAndView mv=new ModelAndView();
student stulogin = stuservice.stulogin(stu);
if(stulogin!=null){
mv.setViewName("index");
return mv;
}
mv.setViewName("login");
return mv;
}
}
applicationContext.xml
<?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" xmlns:mvc="http://www.springframework.org/schema/mvc"
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://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.MckzDubbo.*"/>
<mvc:annotation-driven/>
<context:annotation-config/>
<!-- 配置视图解析器,设置前缀和后缀,自动拼接 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 前缀 -->
<property name="prefix" value="/jsp/" />
<!-- 后缀 -->
<property name="suffix" value=".jsp" />
</bean>
<mvc:default-servlet-handler/>
<!-- 提供方应用信息,用于计算依赖关系 -->
<dubbo:application name="consumer"/>
<!-- 使用zookeeper注册中心暴露服务地址 -->
<dubbo:registry address="127.0.0.1:2181" protocol="zookeeper" />
<!-- 用dubbo协议在20880端口暴露服务 -->
<dubbo:protocol name="dubbo" port="20880" />
<!-- 生成远程服务代理,可以和本地bean一样使用demoService -->
<dubbo:reference id="userService" interface="com.MckzDubbo.service.service" />
</beans>
log4j.properties
### direct log messages to stdout ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
### direct messages to file mylog.log ###
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=F:\\study\\IDEAY2\\smbms\\src\\main\\webapp\\WEB-INF\\log.txt
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
### set log levels - for more verbose logging change 'info' to 'debug' ###
log4j.rootLogger=debug, stdout,file
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<!--Spring和MyBatis整合的核心配置-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!--配置SpringMVC的核心控制器DispatcherServlet-->
<servlet>
<servlet-name>SpringMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:applicationContext.xml</param-value>
</init-param>
</servlet>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet-mapping>
<servlet-name>SpringMVC</servlet-name>
<!--设置映射路径,/代表所有的请求都会被核心控制器映射到对应的Controller中-->
<url-pattern>/</url-pattern>
</servlet-mapping>
<!--编码过滤器-->
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<!--初始化参数-->
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
jsp文件夹
login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" isELIgnored="false" %>
<!DOCTYPE html>
<form action="/student/logins" method="post">
<div>
<input type="text" class="form-control" name="stuname" placeholder="请输入用户名" required="" />
</div>
<div>
<input type="password" class="form-control" name="age" placeholder="请输入密码" required="" />
</div>
<div>
<button type="submit" class="btn btn-success">登 录</button>
<button type="reset" class="btn btn-default">重 填</button>
</div>
</form>
index.jsp
<%--
Created by IntelliJ IDEA.
User: Administrator
Date: 2019/11/30
Time: 15:05
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>登录成功,NB!</h1>
</body>
</html>
注意:
Consumer和Producers各有一个tomcat
优先启动Producers的tomcat
后在启动Consumer即可