说Dubbo之前我们先说一下软件架构的发展史,由浅入深的知道软件架构,从而引出Dubbo,这对于理解Dubbo还是有帮助的。
1、软件架构的发展史
软件架构的发展经历了从单体结构(集中式架构)、垂直架构、分布式架构到微服务架构的过程。
1.1单体架构(集中式架构)
当网站的流量很小的时候,只需要一个应用就可以将所有的功能全都部署在一次 ,以减少部署的节点和成本。
特点:
- 所有的功能集成在一个项目工程中。
- 所有的功能打一个war包部署到服务器。
- 应用与数据库分开部署。
- 通过部署应用集群和数据库集群来提高系统的性能。
缺点:
- 全部功能集成在一个工程中,对于大型项目不易开发、扩展及维护。
- 系统性能扩展只能通过扩展集群结点,成本高、有瓶颈。
1.2 垂直架构
当访问量逐渐增大,单一应用无法满足需求,此时为了应对更高的并发和业务需求,我们根据业务功能对系统进行拆分。
特点:
- 以单体结构规模的项目为单位进行垂直划分项目即将一个大项目拆分成一个一个单体结构项目。
- 项目与项目之间的存在数据冗余,耦合性较大
- 项目之间的接口多为数据同步功能,如:数据库之间的数据库,通过网络接口进行数据库同步。
1.3 分布式架构
当垂直应用越来越多,应用之间交互不可避免,将核心公共业务抽取出来,作为独立的服务,逐渐形成稳定的服务中心,使前端应用能更快速的响应多变的市场需求。此时,用于提高业务复用及整合的分布式调用是关键。
分布式架构的关键:
1.通俗理解: 一件事情分开来做
2. 设计角度: 把公用的业务抽取出来做成独立的服务(独立项目),可以给各个业务系统去调用
-
代码角度: 原来架构是web与service放在一起。现在就把service发布为一个单独的服务。通过地址来访问服务接口的方法。
-
优点:
- 将基础服务进行了抽取,系统间相互调用,提高了代码复用和开发效率
- 每个服务扩展能力强,同时并发能力大大增强
缺点:
- 系统间耦合度变高,调用关系错综复杂,维护变得困难
2、Dubbo入门案例- 服务提供者
Dubbo作为一个RPC框架,其最核心的功能就是要实现跨网络的远程调用。当前入门案例就是要创建两个应用,一个作为服务的提供者,一个作为服务的消费者。通过Dubbo来实现服务消费者远程调用服务提供者的方法。
2.1创建一个Maven工程
2.2 在pom.xml添加依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.zhc1024</groupId>
<artifactId>dubbo_provider</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<spring.version>5.0.2.RELEASE</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- dubbo相关 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.6.6</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.32.Final</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>4.0.0</version>
<exclusions>
<exclusion>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.7</version>
</dependency>
<dependency>
<groupId>com.github.sgroschupf</groupId>
<artifactId>zkclient</artifactId>
<version>0.1</version>
</dependency>
</dependencies>
</project>
2.3 编写web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<!--Spring监听器加载dubbo-provider.xml-->
<!--加载路径-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:dubbo-provider.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
2.4 dubbo-provider.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"
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">
<!--Spring风格编写dubbo配置-->
<!--1.指定服务发布的名称(作用:方便服务消费者查找该服务)注意:在一个大项目,每个服务的名称唯一的-->
<dubbo:application name="dubbo_provider"/>
<!--2.Zookeeper注册配置-->
<dubbo:registry address="zookeeper://192.168.254.88:2181"/>
<!--3.配置dubbo通讯协议(服务消费者与服务提供者之间传输协议)
注意:在一个大项目中,每个服务提供者,dubbo协议端口要唯一
-->
<dubbo:protocol name="dubbo" port="20880"/>
<!--4.扫描Dubbo的@Service注解所在包-->
<dubbo:annotation package="com.zhc1024.impl"/>
</beans>
2.5 编写接口和实现类
编写一个很简单的实现类来演示
2.6 启动
1.先启动zookeeper
2.在配置Tomcat启动
3、编写消费者
创建服务消费者项目,实现服务的消费。也叫做调用服务。
3.1 创建消费者模块
3.2 在pom.xml里添加依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.zhc1024</groupId>
<artifactId>dubbo_consumer</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<spring.version>5.0.2.RELEASE</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- dubbo相关 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.6.6</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.32.Final</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>4.0.0</version>
<exclusions>
<exclusion>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.7</version>
</dependency>
<dependency>
<groupId>com.github.sgroschupf</groupId>
<artifactId>zkclient</artifactId>
<version>0.1</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
</dependencies>
</project>
3.3 编写web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<!--注意:dubbo配置文件 可以使用spring监听器 或者 springmvc核心控制器 来启动-->
<!--启动springmvc-->
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:dubbo-consumer.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
</web-app>
3.4 编写dubbo-consumer.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:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc" 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://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<!--1.springmvc配置: 扫描@Controller注解-->
<!--1.1 扫描Controller类-->
<context:component-scan base-package="com.zhc1024.controller"/>
<!--1.2 mvc注解驱动-->
<mvc:annotation-driven/>
<!--2.dubbo配置(服务消费方)注意:服务消费者不需要指定dubbo协议的-->
<!--2.1 指定服务名称-->
<dubbo:application name="dubbo_consumer"/>
<!--2.2 Zookeeper注册配置-->
<dubbo:registry address="zookeeper://192.168.254.88:2181"/>
<!--2.3 扫描Dubbo的@Reference注解所在包-->
<dubbo:annotation package="com.zhc1024.controller"/>
</beans>
3.5 编写接口和controller
注意:这里的接口类名称要与服务端接口名称一致;路径也要一致。
controller:
package com.zhc1024.controller;
import com.alibaba.dubbo.config.annotation.Reference;
import com.zhc1024.DubboService;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class HelloController {
/**
* 使用@Reference注解进行远程调用
* 注意:必须导入阿里的包:com.alibaba.dubbo.config.annotation.Reference
*/
@Reference
private DubboService dubboService;
@RequestMapping("/hello")
@ResponseBody
public String hello(){
return dubboService.sayHello("张三");
}
}
3.6 启动
先重启提供者,在配置消费者的Tomcat启动
注意修改消费者的端口号
访问成功!
因为没有配置编码,所以会出现乱码现象。
4、总结
总结一下吧,总的来说思路就是提供者和消费者之间有一个注册中心zooKeeper(在配置文件里面体现),提供者把它提供的东西存放到注册中心,消费者就在注册中心里面取出来。就好像两个人不在一起,但是通过注册中心联系到了一起,这就是远程注入。
以上仅为个人见解,我也没有太多的官方词汇,这样有助于新手理解,等有了自己的理解之后再去认真看官方解释会好一点,希望大家共同进步!