首页 » 正文内容 » Dubbo - 初识Apache Dubbo

Dubbo - 初识Apache Dubbo

时间:2023-11-21 10:34:52  热度:0°C

为什么要用Dubbo?

随着互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构越来越流行。和传统的单体架构相比,分布式架构多了一个远程服务之间的通信。无论SOA还是微服务,本质上都是对业务服务的提炼和复用,因此远程服务之间的调用是实现分布式的关键因素。

目前在远程通信这个领域,有很多非常成熟的RPC框架,比如 RMI,WebService,Hessian,Dubbo,Thrift等,即使我们不使用这些RPC框架,我们也可以通过socket或者NIO也可以实现远程通信,那么我们为什么要使用这些现成的RPC框架呢?

原因是因为如果我们自己去开发一个网络通信,需要考虑到下面几点:

  • 底层网络通信协议的处理

  • 序列化和反序列化的工作

  • 这些工作本身就是通用的,不应该由业务人员自己来实现,所以才有了RPC框架,使得开发人员不需要关心底层的通信逻辑。

    同时,当企业开始大规模的服务化之后,我们还需要考虑以下几点:

  • 如何实现对服务链路的***和监控

  • 当服务越来越多时,服务 URL 配置管理变得非常困难,需要服务注册中心来解决服务的发现与感知问题

  • 要有容错机制防止一个节点故障引发大规模 的系统故障

  • 负载均衡进行分发请求

  • 对于这些要求,传统的RPC技术就有些力不从心了,所以很多公司就根据需求研发自己的RPC框架,Dubbo就是其中的一个。

    dubbo 主要是一个分布式服务治理解决方案,那么什么是服务治理?服务治理主要是针对大规模服务化以后,服务之间的路由、负载均衡、容错机制、 服务降级这些问题的解决方案,而 Dubbo 实现的不仅仅是远程服务通信, 并且还解决了服务路由、负载、降级、容错等功能。

    Dubbo的基本使用

    我们先通过一个简单的demo来初步了解一下Dubbo的基本用法

    1/ 创建两个项目dubbo-pratice-service 和dubbo-pratice-client。dubbo-pratice-service这个工程中包含两个子工程,practice-service-api和practice-service-provider。

    2/ dubbo-pratice-service这个工程中包含两个子工程,practice-service-api和practice-service-provider,dubbo-practice-service工程作为父工程来管理版本信息,pom/xml文件如下:dubbo-practice-service的pom文件:

    </?xml version= 1/0 encoding= UTF-8 ?>/</project xmlns= /POM/4/0/0 xmlns/xsi= /2001/XMLSchema-instance xsi/schemaLocation= /POM/4/0/0 /xsd/maven-4/0/0/xsd >/ </modelVersion>/4/0/0<//modelVersion>/ </groupId>/com/yrk/dubbo<//groupId>/ </artifactId>/dubbo-practice-service<//artifactId>/ </version>/0/0/1-SNAPSHOT<//version>/ </packaging>/pom<//packaging>/ </modules>/ </module>/practice-service-api<//module>/ </module>/practice-service-provider<//module>/ <//modules>/ </dependencyManagement>/ </dependencies>/ </dependency>/ </groupId>/junit<//groupId>/ </artifactId>/junit<//artifactId>/ </version>/3/8/1<//version>/ </scope>/test<//scope>/ <//dependency>/ </dependency>/ </groupId>/org/apache/dubbo<//groupId>/ </artifactId>/dubbo<//artifactId>/ </version>/2/7/2<//version>/ <//dependency>/ </dependency>/ </groupId>/org/slf4j<//groupId>/ </artifactId>/slf4j-api<//artifactId>/ </version>/1/7/26<//version>/ <//dependency>/ </dependency>/ </groupId>/ch/qos/logback<//groupId>/ </artifactId>/logback-classic<//artifactId>/ </version>/1/2/3<//version>/ <//dependency>/ <//dependencies>/ <//dependencyManagement>/<//project>/

    通过dependencyManagement来管理项目中依赖的lib的版本。3/ practice-service-api这个工程用来维护所提供服务的api,目录结构如下:

    4/ practice-service-api的pom文件如下:

    </?xml version= 1/0 ?>/</project xsi/schemaLocation= /POM/4/0/0 /xsd/maven-4/0/0/xsd xmlns= /POM/4/0/0 xmlns/xsi= /2001/XMLSchema-instance >/ </modelVersion>/4/0/0<//modelVersion>/ </parent>/ </groupId>/com/yrk/dubbo<//groupId>/ </artifactId>/dubbo-practice-service<//artifactId>/ </version>/0/0/1-SNAPSHOT<//version>/ <//parent>/ </artifactId>/practice-service-api<//artifactId>/ </version>/0/0/1-SNAPSHOT<//version>/ </name>/practice-service-api<//name>/ </url>/<//url>/ </properties>/ </project/build/sourceEncoding>/UTF-8<//project/build/sourceEncoding>/ <//properties>/ </dependencies>/ </dependency>/ </groupId>/junit<//groupId>/ </artifactId>/junit<//artifactId>/ </scope>/test<//scope>/ <//dependency>/ <//dependencies>/<//project>/

    同时在practice-service-api这个工程中定义LoginService接口:

    public interface LoginService { String login(String username/ String password)/}

    5/ practice-service-provider工程用来提供服务的实现,项目结构如下:

    6/ practice-service-provider的pom文件如下:

    </?xml version= 1/0 ?>/</project xsi/schemaLocation= /POM/4/0/0 /xsd/maven-4/0/0/xsd xmlns= /POM/4/0/0 xmlns/xsi= /2001/XMLSchema-instance >/ </modelVersion>/4/0/0<//modelVersion>/ </parent>/ </groupId>/com/yrk/dubbo<//groupId>/ </artifactId>/dubbo-practice-service<//artifactId>/ </version>/0/0/1-SNAPSHOT<//version>/ <//parent>/ </artifactId>/practice-service-provider<//artifactId>/ </name>/practice-service-provider<//name>/ </url>/<//url>/ </properties>/ </project/build/sourceEncoding>/UTF-8<//project/build/sourceEncoding>/ <//properties>/ </dependencies>/ </dependency>/ </groupId>/junit<//groupId>/ </artifactId>/junit<//artifactId>/ </scope>/test<//scope>/ <//dependency>/ </dependency>/ </groupId>/org/apache/dubbo<//groupId>/ </artifactId>/dubbo<//artifactId>/ <//dependency>/ </dependency>/ </groupId>/org/slf4j<//groupId>/ </artifactId>/slf4j-api<//artifactId>/ <//dependency>/ </dependency>/ </groupId>/ch/qos/logback<//groupId>/ </artifactId>/logback-classic<//artifactId>/ <//dependency>/ </dependency>/ </groupId>/com/yrk/dubbo<//groupId>/ </artifactId>/practice-service-api<//artifactId>/ </version>/0/0/1-SNAPSHOT<//version>/ <//dependency>/ <//dependencies>/<//project>/

    7/ 为LoginService接口提供实现类:

    package org/practice/service/provider/import org/practice/service/api/LoginService/public class LoginServiceImpl implements LoginService{ public String login(String username/ String password) { if ( admin /equalsIgnoreCase(username) &/&/ admin /equalsIgnoreCase(password)) { return Success / } return Failed / }}

    接下来我们使用xml的形式通过dubbo来发布服务:我们需要在resources目录下面新建META-INF/spring目录,同时在这个目录下面新建application/xml文件,我们需要在这个文件中定义dubbo相关的信息:application/xml/

    </beans xmlns/xsi= /2001/XMLSchema-instance xmlns/dubbo= /schema/dubbo xmlns= /schema/beans xsi/schemaLocation= /schema/beans /schema/beans/spring-beans/xsd /schema/dubbo /schema/dubbo/dubbo/xsd >/ </!-- 服务提供方应用信息 -->/ </dubbo/application name= practice-service />/ </!-- 使用multicast 广播注册中心暴露服务地址 -->/ </dubbo/registry address= N/A />/ </!-- 使用dubbo协议在20880端口暴露服务 -->/ </dubbo/protocol name= dubbo port= 20880 />/ </!-- 声明需要暴露的服务接口 -->/ </dubbo/service interface= org/practice/service/api/LoginService ref= loginService />/ </bean id= loginService class= org/practice/service/provider/LoginServiceImpl />/ <//beans>/

    然后通过Main/main(args)来启动服务:

    package org/practice/service/provider/import org/apache/dubbo/container/Main/public class App { public static void main( String[] args ){ Main/main(args)/ }}

    启动服务的时候回在console中看到如下信息

    2019-08-15 08/41/38/720 INFO [main] o/a/dubbo/config/AbstractConfig - [DUBBO] Export dubbo service org/practice/service/api/LoginService to local registry url / injvm///127/0/0/1/org/practice/service/api/LoginService?anyhost=true&/application=practice-service&/bean/name=org/practice/service/api/LoginService&/bind/ip=xxxx&/bind/port=20880&/deprecated=false&/dubbo=2/0/2&/dynamic=true&/generic=false&/interface=org/practice/service/api/LoginService&/methods=login&/pid=11664&/register=true&/release=2/7/2&/side=provider&/timestamp=1565829698502/ dubbo version/ 2/7/2/ current host/ xxxx2019-08-15 08/41/38/723 INFO [main] o/a/dubbo/config/AbstractConfig - [DUBBO] Export dubbo service org/practice/service/api/LoginService to url dubbo///xxxx/20880/org/practice/service/api/LoginService?anyhost=true&/application=practice-service&/bean/name=org/practice/service/api/LoginService&/bind/ip=xxxx&/bind/port=20880&/deprecated=false&/dubbo=2/0/2&/dynamic=true&/generic=false&/interface=org/practice/service/api/LoginService&/methods=login&/pid=11664&/register=true&/release=2/7/2&/side=provider&/timestamp=1565829698502/ dubbo version/ 2/7/2/ current host/ xxxx

    其中dubbo///xxxx/20880/org/practice/service/api/LoginService就是我们我们服务的url。

    8/ dubbo-practice-client工程是服务调用的客户端,pom文件如下:

    </project xmlns= /POM/4/0/0 xmlns/xsi= /2001/XMLSchema-instance xsi/schemaLocation= /POM/4/0/0 /xsd/maven-4/0/0/xsd >/ </modelVersion>/4/0/0<//modelVersion>/ </groupId>/com/yrk/dubbo<//groupId>/ </artifactId>/dubbo-practice-client<//artifactId>/ </version>/0/0/1-SNAPSHOT<//version>/ </packaging>/jar<//packaging>/ </name>/dubbo-practice-client<//name>/ </url>/<//url>/ </properties>/ </project/build/sourceEncoding>/UTF-8<//project/build/sourceEncoding>/ <//properties>/ </dependencies>/ </dependency>/ </groupId>/junit<//groupId>/ </artifactId>/junit<//artifactId>/ </version>/3/8/1<//version>/ </scope>/test<//scope>/ <//dependency>/ </dependency>/ </groupId>/org/apache/dubbo<//groupId>/ </artifactId>/dubbo<//artifactId>/ </version>/2/7/2<//version>/ <//dependency>/ </dependency>/ </groupId>/org/slf4j<//groupId>/ </artifactId>/slf4j-api<//artifactId>/ </version>/1/7/26<//version>/ <//dependency>/ </dependency>/ </groupId>/ch/qos/logback<//groupId>/ </artifactId>/logback-classic<//artifactId>/ </version>/1/2/3<//version>/ <//dependency>/ </dependency>/ </groupId>/com/yrk/dubbo<//groupId>/ </artifactId>/practice-service-api<//artifactId>/ </version>/0/0/1-SNAPSHOT<//version>/ <//dependency>/ <//dependencies>/<//project>/

    在resources目录下创建application/xml文件,内容如下:

    </beans xmlns/xsi= /2001/XMLSchema-instance xmlns/dubbo= /schema/dubbo xmlns= /schema/beans xsi/schemaLocation= /schema/beans /schema/beans/spring-beans/xsd /schema/dubbo /schema/dubbo/dubbo/xsd >/ </!-- 服务提供方应用信息 -->/ </dubbo/application name= practice-client />/ </dubbo/registry address= N/A />/ </!-- 通过reference标签获取服务 -->/ </dubbo/reference id= loginService interface= org/practice/service/api/LoginService url= dubbo///172/17/23/32/20880/org/practice/service/api/LoginService />/ <//beans>/

    在Main方法中获取loginService并调用login方法:

    public class App { public static void main( String[] args ) { System/out/println( Hello World! )/ ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] { application/xml })/ LoginService loginService = (LoginService) context/getBean( loginService )/ System/out/println(loginService/login( admin / admin ))/ }}

    运行之后可以在控制台中看到结果:

    2019-08-15 10/38/26/811 DEBUG [NettyClientWorker-1-1] i/n/u/ResourceLeakDetectorFactory - Loaded default ResourceLeakDetector/ io/netty/util/ResourceLeakDetector@6bf5b77a2019-08-15 10/38/27/251 DEBUG [DubboClientHandler-172/17/23/32/20880-thread-1] o/a/d/r/transport/DecodeHandler - [DUBBO] Decode decodeable message org/apache/dubbo/rpc/protocol/dubbo/DecodeableRpcResult/ dubbo version/ 2/7/2/ current host/ 172/17/23/32Success

    表明远程服务调用成功。

    关于 Dubbo 启动的***

    通过上面的例子,我们用Dubbo实现了一个非常简单的远程服务调用,同时在上面的例子中,我们并没有使用到tomcat、jetty这类容器,那么Dubbo是如何实现的呢?

    其实Dubbo内部提供了几种容器供我们使用去启动和发布服务:Spring Container/自动加载META-INF/spring目录下的所有spring配置logback Container/自动装配logback日志Log4j Container/自动配置log4j的配置

    同时Dubbo提供了一个Main/main方法可以快速启动相应的容器,默认情况下只会启动spring容器,Spring容器的类是SpringContainer/java,启动的代码如下:

    public static final String SPRING_CONFIG = dubbo/spring/config / public static final String DEFAULT_SPRING_CONFIG = classpath*/META-INF/spring/*/xml / private static final Logger logger = LoggerFactory/getLogger(SpringContainer/class)/ static ClassPathXmlApplicationContext context/ public static ClassPathXmlApplicationContext getContext() { return context/ } @Override public void start() { String configPath = ConfigUtils/getProperty(SPRING_CONFIG)/ if (StringUtils/isEmpty(configPath)) { configPath = DEFAULT_SPRING_CONFIG/ } context = new ClassPathXmlApplicationContext(configPath/split( [/\s]+ )/ false)/ context/refresh()/ context/start()/ }

    免责声明:
    1. 《Dubbo - 初识Apache Dubbo》内容来源于互联网,版权归原著者或相关公司所有。
    2. 若《65667893文库网》收录的文本内容侵犯了您的权益或隐私,请立即通知我们删除。