分布式RPC框架Apache Dubbo

分布式RPC框架Apache Dubbo,第1张

分布式RPC框架Apache Dubbo 1、Apache Dubbo概述 1.1 Dubbo简介

Apache Dubbo是一款高性能的Java RPC框架。其前身是阿里巴巴公司开源的、轻量级的开源Java RPC 框架,可以和Spring框架无缝集成,2018年阿里巴巴把这个框架捐献给了apache基金会

Dubbo提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发 现。

Dubbo官方推荐使用Zookeeper作为服务注册中心。

2. Dubbo快速入门

Dubbo作为一个RPC框架,其最核心的功能就是要实现跨网络的远程调用。本小节就是要创建两个应 用,一个作为服务的提供方,一个作为服务的消费方。通过Dubbo来实现服务消费方远程调用服务提供 方的方法。

2.1 服务提供方开发

(1)创建maven工程,导入dubbo相关的坐标


    UTF-8
    1.8
    1.8
    5.0.5.RELEASE


    
    org.springframework
        spring-context
        ${spring.version}
    
    
        org.springframework
        spring-beans
        ${spring.version}
    
    
        org.springframework
        spring-webmvc
        ${spring.version}
    
    
        org.springframework
        spring-jdbc
        ${spring.version}
    
    
        org.springframework
        spring-aspects
        ${spring.version}
    
    
        org.springframework
        spring-jms
        ${spring.version}
    
    
        org.springframework
        spring-context-support
        ${spring.version}
    
    
    
        com.alibaba
        dubbo
        2.6.0
    
    
        org.apache.zookeeper
        zookeeper
        3.4.7
    
    
        com.github.sgroschupf
        zkclient
    0.1
    
    
        javassist
        javassist
        3.12.1.GA
    
    
        com.alibaba
        fastjson
        1.2.47
    


    
        
            org.apache.maven.plugins
            maven-compiler-plugin
            2.3.2
            
                1.8
                1.8
            
        
        
            org.apache.tomcat.maven
            tomcat7-maven-plugin
            
            
            8081
            
            /
            
        
    

(2)配置web.xml文件

(3)创建服务接口

package com.lxs.service;

public interface HelloService {
    public String sayHello(String name);
}

(4)创建服务实现类

package com.lxs.service.impl;
import com.alibaba.dubbo.config.annotation.Service;
import com.lxs.service.HelloService;
@Service
public class HelloServiceImpl implements HelloService {
    public String sayHello(String name) {
        return "hello " + name;
    }
}

注意:服务实现类上使用的Service注解是Dubbo提供的,用于对外发布服务

(5)在src/main/resources下创建applicationContext-service.xml



    
    
    
    
    
    
    
    

(6)启动服务 tomcat7:run

2.2 服务消费方开发

(1)创建maven工程,导入dubbo相关的坐标

(2)配置web.xml文件

(3)将服务提供者工程中的HelloService接口复制到当前工程

(4)编写Controller

package com.lxs.controller;
import com.alibaba.dubbo.config.annotation.Reference;
import com.lxs.service.HelloService;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
@RequestMapping("/demo")
public class HelloController {
    @Reference
    private HelloService helloService;
    @RequestMapping("/hello")
    @ResponseBody
    public String getName(String name){
        //远程调用
        String result = helloService.sayHello(name);
        System.out.println(result);
        return result;
    }
}

注意:Controller中注入HelloService使用的是Dubbo提供的@Reference注解

(5)在src/main/resources下创建applicationContext-web.xml



    
    
    
    
    
    

(6)运行测试 tomcat7:run启动

在浏览器输入http://localhost:8082/demo/hello.do?name=Jack,查看浏览器输出结果

思考一:

上面的Dubbo入门案例中我们是将HelloService接口从服务提供者工程 (dubbodemo_provider)复制到服务消费者工程(dubbodemo_consumer)中,这种做法是否合适?还有 没有更好的方式? 答:这种做法显然是不好的,同一个接口被复制了两份,不利于后期维护。更好的方式是单独创建一个 maven工程,将此接口创建在这个maven工程中。需要依赖此接口的工程只需要在自己工程的 pom.xml文件中引入maven坐标即可。

思考二:

在服务消费者工程(dubbodemo_consumer)中只是引用了HelloService接口,并没有提供实现 类,Dubbo是如何做到远程调用的? 答:Dubbo底层是基于代理技术为HelloService接口创建代理对象,远程调用是通过此代理对象完成 的。可以通过开发工具的debug功能查看此代理对象的内部结构。另外,Dubbo实现网络传输底层是基 于Netty框架完成的。

思考三:

上面的Dubbo入门案例中我们使用Zookeeper作为服务注册中心,服务提供者需要将自己的服 务信息注册到Zookeeper,服务消费者需要从Zookeeper订阅自己所需要的服务,此时Zookeeper服务 就变得非常重要了,那如何防止Zookeeper单点故障呢? 答:Zookeeper其实是支持集群模式的,可以配置Zookeeper集群来达到Zookeeper服务的高可用,防 止出现单点故障。

3. Dubbo管理控制台(自行安装) 4. Dubbo相关配置说明 4.1 包扫描

服务提供者和服务消费者都需要配置,表示包扫描,作用是扫描指定包(包括子包)下的类。

4.2 协议

一般在服务提供者一方配置,可以指定使用的协议名称和端口号。

其中Dubbo支持的协议有:dubbo、rmi、hessian、http、webservice、rest、redis等。

推荐使用的是dubbo协议。

dubbo 协议采用单一长连接和 NIO 异步通讯,适合于小数据量大并发的服务调用,以及服务消费者机 器数远大于服务提供者机器数的情况。不适合传送大数据量的服务,比如传文件,传视频等,除非请求 量很低。也可以在同一个工程中配置多个协议,不同服务可以使用不同的协议

4.3 负载均衡

负载均衡(Load Balance):其实就是将请求分摊到多个 *** 作单元上进行执行,从而共同完成工作任务。

在集群负载均衡时,Dubbo 提供了多种均衡策略(包括随机、轮询、最少活跃调用数、一致性 Hash),缺省为random随机调用。

配置负载均衡策略,既可以在服务提供者一方配置,也可以在服务消费者一方配置:

@Controller
@RequestMapping("/demo")
public class HelloController {

    //在服务消费者一方配置负载均衡策略
    @Reference(check = false,loadbalance = "random")
    private HelloService helloService;

    @RequestMapping("/hello")
    @ResponseBody
    public String getName(String name){
        //远程调用
        String result = helloService.sayHello(name);
        System.out.println(result);
        return result;
    }
}

//或者

//在服务提供者一方配置负载均衡
@Service(loadbalance = "random")
public class HelloServiceImpl implements HelloService {
    public String sayHello(String name) {
        return "hello " + name;
    }
}
5. 解决Dubbo无法发布被事务代理的Service问题

如果在服务提供者类上加入@Transactional事务控制注解后,服务就发布不成功了。原因是事 务控制的底层原理是为服务提供者类创建代理对象,而默认情况下Spring是基于JDK动态代理方式创建代理对象,而此代理对象的完整类名为com.sun.proxy.$Proxy42(最后两位数字不是固定的),导致 Dubbo在发布服务前进行包匹配时无法完成匹配,进而没有进行服务的发布。

解决方案:

在HelloServiceImpl类上加入事务注解后,Spring会为此类基于JDK动 态代理技术创建代理对象,创建的代理对象完整类名为com.sun.proxy.$Proxy35,导致Dubbo在进行 包匹配时没有成功(因为我们在发布服务时扫描的包为com.lxs.service),所以后面真正发布服务的代码没有执行。

解决方式 *** 作步骤:

(1)修改applicationContext-service.xml配置文件,开启事务控制注解支持时指定proxy-target-class 属性,值为true。其作用是使用cglib代理方式为Service类创建代理对象

(2)修改HelloServiceImpl类,在Service注解中加入interfaceClass属性,值为HelloService.class, 作用是指定服务的接口类型

//cglib代理默认服务接口为SpringProxy,而不是HelloService接口
@Service(interfaceClass = HelloService.class)
@Transactional
public class HelloServiceImpl implements HelloService {
    public String sayHello(String name) {
        return "hello " + name;
    }
}

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5679167.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存