
大家好,我是哪吒。
今天详细的分解一下Dubbo的扩展机制,实现快速入门,丰富个人简历,提高面试level,给自己增加一点谈资,秒变面试小达人,BAT不是梦。
说真的,从零学习Dubbo,看这个系列足够了,共10篇,欢迎持续关注,相约每天早八点。
三分钟你将学会:
Dubbo 是一款开源的分布式服务框架,它为分布式系统的开发和部署提供了便捷的方式。在 Dubbo 中,服务消费是非常重要的一部分,它是 Dubbo 服务分布式架构的重要组成部分。

本文将详细介绍 Dubbo 服务消费,包括 Dubbo 服务消费的基础知识、注册与发现、消息代理、负载均衡、安全控制、监控和日志等方面的内容。
Dubbo 服务消费是 Dubbo 服务分布式架构的重要组成部分,它主要负责服务的消费和调用。
在 Dubbo 中,服务消费是通过注册中心和发布中心来实现的。
注册中心负责服务的注册和发现,发布中心负责服务的发布和广播。Dubbo 服务消费提供了多种消息代理技术,如 Apache Kafka、RabbitMQ 等,可以支持大规模的分布式系统的高效消费和发布。
Dubbo 服务消费的目的是为了帮助开发者更深入地了解 Dubbo 服务消费的工作原理和配置方法,以及掌握 Dubbo 服务消费的核心概念和技术,从而更好地使用 Dubbo 框架来构建分布式系统。
同时,随着分布式系统的开发和部署的不断普及,了解 Dubbo 服务消费也是开发者必备的技能之一。
Dubbo 服务消费的过程可以概括为以下几个步骤:

Dubbo 服务消费的过程
上图描述了Dubbo服务消费的过程,其中:
在整个过程中,Dubbo通过Registry、Directory、LoadBalance、Invoker等组件实现了服务的注册、发现、负载均衡、调用等功能,提供了完整的分布式服务治理方案。

在 Dubbo 服务消费中,核心概念主要包括:

Dubbo 服务消费的架构和流程
以上是Dubbo服务消费的架构和流程,其中消费方向注册中心查询可用服务,然后向其中一台服务提供方发起请求,收到响应后再向另一台服务提供方发起请求并接收响应。
Dubbo服务消费的基本配置和使用方法需要以下步骤:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>x.x.x</version>
</dependency><dubbo:application name="consumer" />
<dubbo:registry address="zookeeper://localhost:2181" />
<dubbo:consumer check="false" />
<dubbo:reference id="userService" interface="com.xxx.UserService" />public class UserController {
@Autowired
private UserService userService;
public User getUserById(Long id) {
return userService.getUserById(id);
}
}
服务消费的注册中心是负责服务消费方 (即客户端) 注册和发现的组件。
当服务消费方需要调用服务时,它会首先向注册中心发送注册请求,注册中心会记录下该客户端的注册信息,包括客户端的 IP 地址、端口号、客户端认证信息等。当服务需要被消费时,注册中心会根据客户端的注册信息,自动查找可用的服务实例,并将调用请求发送给服务实例。
服务消费的注册中心通常使用一些开源的框架来实现,比如 Zookeeper、Consul 等。
它们的特点是:
服务消费的发布中心是负责服务发布和发现的组件。当服务提供者需要提供服务时,它会向注册中心发送发布请求,注册中心会记录下该服务提供者的发布信息,包括服务提供者的 IP 地址、端口号、服务版本号等。
当服务消费者需要找到可用的服务时,注册中心会根据服务提供者的发布信息,自动查找可用的服务实例,并将调用请求发送给服务实例。
服务发布的中心通常使用一些开源的框架来实现,比如 Zookeeper、Consul 等。
它们的特点是:

Dubbo 服务消费的注册与发现的工作原理和流程
以上Dubbo 服务消费的注册与发现的工作原理和流程的时序图和说明。

Dubbo 服务消费的注册与发现是基于 Zookeeper 实现的,以下是一个简单的配置和使用代码示例:
首先,需要在 Dubbo 项目的依赖中包含 Zookeeper 依赖包,并且需要在 application.properties 文件中配置 Zookeeper 的地址、端口号等信息,如下所示:
zookeeper://127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183/ DubboZookeeper?zkServers=127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183
DubboApplication.main(args=['config.properties'])其中,zoo_sample.zkServers 属性配置了 Dubbo 项目的 Zookeeper 服务器地址和端口号,DubboApplication 是 Dubbo 的主类,参数 args 中包含了配置的配置文件信息。
在 Dubbo 项目中,需要创建一个服务提供者,并在其中配置 Zookeeper 的地址、端口号等信息,如下所示:
@Component
@Stateless
public class MyService implements MyServiceInterface {
@Override
public String sayHello() {
return "Hello,nezhage!";
}
}其中,MyServiceInterface 是服务提供者实现的接口,MyService 是具体的服务提供者实现类。
在 Dubbo 项目中,需要创建一个服务消费者,并在其中配置 Zookeeper 的地址、端口号等信息,如下所示:
@Component
@Service
public class MyConsumer {
private final static String ZOERO_PATH = "zoo_sample";
private final static String ZOCK_PASSWORD = "mypassword";
private final static String STANDALONE = "standalone";
@Autowired
private MyServiceInterface myService;
public void consume(String message) {
System.out.println("Received message: " + message);
myService.sayHello();
}
}其中,MyConsumer 是具体的服务消费者实现类,它通过注入 MyServiceInterface 实现了对服务提供者的调用。
在 Zookeeper 中创建了服务消费者和服务提供者之后,需要使用命令行启动它们,如下所示:
java -cp dubbo-sample-assembly-1.0.0.jar:dubbo-application-1.0.0.jar:zookeeper-3.4.6.jar:org.apache.zookeeper_3.4.6.jar MyConsumer
java -cp dubbo-sample-assembly-1.0.0.jar:dubbo-application-1.0.0.jar:zookeeper-3.4.6.jar:org.apache.zookeeper_3.4.6.jar MyService其中,MyConsumer 和 MyService 分别是服务消费者和服务提供者的主类名,可以根据实际情况进行修改。
启动服务提供者和消费者之后,可以使用命令行进行测试,如下所示:
java -cp dubbo-sample-assembly-1.0.0.jar:dubbo-application-1.0.0.jar:zookeeper-3.4.6.jar:org.apache.zookeeper_3.4.6.jar com.example.consumer MyConsumer
java -cp dubbo-sample-assembly-1.0.0.jar:dubbo-application-1.0.0.jar:zookeeper-3.4.6.jar:org.apache.zookeeper_3.4.6.jar com.example.service MyService
Dubbo 服务消费的消息代理是 Dubbo 框架中的一个重要组件,它用于实现服务消费者的远程调用,并支持负载均衡和容错等功能。
Dubbo 服务消费的消息代理主要特点如下:
Dubbo 服务消费的消息代理工作原理如下:
当服务消费者需要调用服务提供者时,它会向 Dubbo 消息代理发送消息,请求 Dubbo 消息代理将请求转发给服务提供者。Dubbo 消息代理接收到这个消息后,会将这个消息封装成一个 Dubbo 请求对象,并使用 Dubbo 请求对象的 API 调用服务提供者。
服务提供者接收到 Dubbo 请求对象后,会根据请求对象中的数据,执行相应的操作,并将结果返回给 Dubbo 消息代理。Dubbo 消息代理接收到服务提供者返回的消息后,会将消息解封,并调用服务消费者 API 中相应的方法,将结果返回给服务消费者。
Dubbo 服务消费的消息代理的流程如下:

Dubbo 服务消费的消息代理的流程
流程说明:

在 Dubbo 项目中创建一个名为 message-proxy.xml 的文件,用于配置 Dubbo 消息代理。
在该文件中,需要配置以下信息:
在需要启用 Dubbo 消息代理的类上添加 @EnableMessageProxy 注解,例如:
@Component
@EnableMessageProxy
public class MyConsumer {
// ...
}在需要使用 Dubbo 消息代理的服务消费者中添加消息代理的配置信息,例如:
@Service
public class MyConsumer {
@Autowired
private MyMessageProxy messageProxy;
public void consume(String message) {
System.out.println("Received message: " + message);
MyMessageProxy.outboundMessageHandler(message);
}
}在该代码中,MyMessageProxy 是 Dubbo 消息代理的实现类,outboundMessageHandler 方法用于将接收到的消息代理到 Dubbo 消息代理中进行处理。
在控制台中启动 Dubbo 消息代理服务,例如:
java -cp /path/to/dubbo-2.7.4.jar:/path/to/dubbo-reflection-2.7.4.jar:/path/to/commons-lang-2.6.jar:/path/to/grouper-core-6.2.0.jar:/path/to/zookeeper-3.4.6.jar:/path/to/dubbo-zookeeper-2.7.4.jar org.apache.dubbo.rpc.receiver.ReceiverStartUtil.start(ReceiverStartUtil.java:35)在控制台中可以查看 Dubbo 消息代理的运行状态和日志信息。
通过以上步骤,就可以使用 Dubbo 消息代理实现服务消费者的远程调用,并支持负载均衡和容错等功能。
Dubbo 服务消费的负载均衡的工作原理可以概括为以下几个步骤:
在 Dubbo 中,负载均衡器通常是通过路由器、交换机等组件来实现的。路由器用于将请求转发到不同的服务实例上,交换机用于管理多个服务实例的连接状态。同时,Dubbo 还支持自定义负载均衡算法,用户可以通过编写自定义的负载均衡算法来实现特定的负载均衡策略。
Dubbo 服务消费的负载均衡的流程如下:

Dubbo 服务消费的负载均衡的流程
流程说明:
在 Dubbo 的配置文件中,可以使用负载均衡相关的配置项来指定负载均衡策略和权重。例如:
<dubbo:service interface="com.example.demo.HelloService"
name="hello" port="8080"
loadBalancer-class="com.alibaba.csp.负载均衡.helpers.DefaultLoadBalance">
<dubbo:import key="bootstrap.properties"/>
<dubbo:reference id="helloService" interface="com.example.demo.HelloService"/>
</dubbo:service>在上面的配置中,loadbalance-class 属性指定了负载均衡器的类型为 com.alibaba.csp.负载均衡.helpers.DefaultLoadBalance,它实现了一个简单的负载均衡算法,将请求轮流分配给服务实例。weight 属性指定了每个服务实例的权重,权重值越大,请求被分配到该服务实例的概率就越大。
在 Dubbo 的接口上,可以使用 @LoadBalance 注解来指定负载均衡策略和权重。
例如:
@Service
public class MyService {
@LoadBalance
public String sayHello(String name) {
return "Hello, " + name;
}
}在上面的代码中,@LoadBalance 注解指定了负载均衡策略为 @LoadBalance.Strategy 中的 轮询策略,并且使用了 @LoadBalance.Weight 注解来指定每个服务实例的权重。具体来说,权重值 1.0 表示该服务实例处理请求的概率为 100%,而权重值 0.5 表示该服务实例处理请求的概率为 50%。
需要注意的是,负载均衡器的配置和使用方式可能因具体情况而异,具体实现方式需要根据具体需求进行调整。

Dubbo 服务消费的安全控制是指在服务消费过程中,对服务请求进行安全过滤和认证,以确保服务请求的安全性和可靠性。
下面是 Dubbo 服务消费的安全控制的基本概念和特点:

Dubbo 服务消费的安全控制的流程
上面中,服务消费者通过 Dubbo 消息代理向服务提供者发起请求,请求中包含了安全信息。
Dubbo 服务消费的安全控制可以通过配置来实现,以下是 Dubbo 服务消费的安全控制的配置方法:
要在 Dubbo 服务消费中使用加密技术,需要先配置加密组件。具体来说,需要配置加密钥、加密算法、签名算法等参数。
例如:
import java.util.Properties;
public class SecurityConfig {
//私有静态常数,表示密钥和算法
private static final String SECRET_KEY = "your-secret-key";
private static final String ALGORITHM = "your-algorithm";
private static final String SIGNATURE_ALGORITHM = "your-signature-algorithm";
public static void main(String[] args) throws Exception {
//创建一个新的Properties对象,将所有安全属性与其值存储在其中
Properties props = new Properties();
props.put("security.algorithm", ALGORITHM);
props.put("security.key-store.type", "jks");
props.put("security.key-store.location", "path/to/your/keystore");
props.put("security.key-store.password", "your-keystore-password");
props.put("security.key-store.alias", "your-keystore-alias");
props.put("security.key-store.type", "jks");
//获取其他必要的属性和值
String keystorePath = props.getProperty("security.key-store.location");
String keystorePassword = props.getProperty("security.key-store.password");
String keystoreAlias = props.getProperty("security.key-store.alias");
String algorithm = props.getProperty("security.algorithm");
String secretKey = props.getProperty("security.key-store.password");
//使用JKS格式加载密钥库
KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(new FileInputStream(keystorePath), keystorePassword.toCharArray());
//使用SunX509算法初始化密钥管理器工厂,此算法是用于X.509证书管理的标准
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
keyManagerFactory.init(keyStore, keystorePassword.toCharArray());
//使用指定算法初始化SSL上下文
SSLContext sslContext = SSLContext.getInstance(algorithm);
//初始化SSL上下文与公钥证书相关联的KeyManagers,并使用X509TrustManager进行身份验证
sslContext.init(keyManagerFactory.getKeyManagers(), new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(X509Certificate[] certs, String authType) {
//...
}
public void checkServerTrusted(X509Certificate[] certs, String authType) {
///...
}
}, new SecureRandom());
//使用指定算法初始化加密密码
Cipher cipher = Cipher.getInstance(algorithm);
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
//创建自定义的SocketFactory实例,使用SslSocket套接字进行加密通信
sslContext.setSSLSocketFactory(new SocketFactory() {
public Socket createSocket(String host, int port, InetAddress localAddress, int localPort) throws SocketException {
return new SslSocket(host, port, localAddress, localPort, cipher);
}
});
//创建SSL套接字并连接到服务器
SSLSocket sslSocket = (SSLSocket) sslContext.getSocketFactory().createSocket();
sslSocket.connect(new InetSocketAddress(host, port), 443);
System.out.println("Connected to server");
//开始SSL握手,建立安全连接
sslSocket.startHandshake();
System.out.println("Handshake completed");
}
}在上面的配置中,需要将 SECRET_KEY、ALGORITHM、SIGNATURE_ALGORITHM 等参数设置为合适的值,以实现加密和认证功能。
在 Dubbo 中,服务消费的负载均衡可以用来提高服务的可用性和性能,它可以通过配置和注解两种方式来实现。
下面分别给出这两种方式的代码示例:
在 Dubbo 的配置文件中,可以使用负载均衡相关的配置项来指定负载均衡策略和权重。
例如:
<dubbo:service interface="com.example.demo.HelloService"
name="hello" port="8080" loadbalance-class="com.alibaba.csp.负载均衡.helpers.DefaultLoadBalance">
<dubbo:import key="bootstrap.properties"/>
<dubbo:reference id="helloService" interface="com.example.demo.HelloService"/>
</dubbo:service>在上面的配置中,loadbalance-class 属性指定了负载均衡器的类型为 com.alibaba.csp.负载均衡.helpers.DefaultLoadBalance,它实现了一个简单的负载均衡算法,将请求轮流分配给服务实例。weight 属性指定了每个服务实例的权重,权重值越大,请求被分配到该服务实例的概率就越大。
在 Dubbo 的接口上,可以使用 @LoadBalance 注解来指定负载均衡策略和权重。例如:
@Service
public class MyService {
@LoadBalance
public String sayHello(String name) {
return "Hello, " + name;
}
}在上面的代码中,@LoadBalance 注解指定了负载均衡策略为 @LoadBalance.Strategy 中的 轮询策略,并且使用了 @LoadBalance.Weight 注解来指定每个服务实例的权重。具体来说,权重值 1.0 表示该服务实例处理请求的概率为 100%,而权重值 0.5 表示该服务实例处理请求的概率为 50%。
在 Dubbo 中,服务消费的加密和认证技术可以用来保护服务请求的隐私和安全。
下面分别介绍这两种技术的使用方式:
Dubbo 支持多种加密技术,包括 SHA-256 签名、RSA 签名、HTTPS 加密等。
在使用加密技术时,需要先配置加密组件,例如:
<dubbo:service interface="com.example.demo.HelloService"
name="hello" port="8080" 加密="true">
<dubbo:import key="bootstrap.properties"/>
<dubbo:reference id="helloService" interface="com.example.demo.HelloService"/>
</dubbo:service>在上面的配置中,加密="true" 表示启用加密技术,使用了 SHA-256 签名。在服务消费过程中,客户端会使用加密技术对服务请求进行签名,服务端会验证签名来确保请求的安全性。
Dubbo 支持多种认证技术,包括 Basic 认证、SSL 认证、OAuth 认证等。
在使用认证技术时,需要先配置认证组件,例如:
<dubbo:service interface="com.example.demo.HelloService"
name="hello" port="8080" 认证="true">
<dubbo:import key="bootstrap.properties"/>
<dubbo:reference id="helloService" interface="com.example.demo.HelloService"/>
</dubbo:service>在上面的配置中,认证="true" 表示启用认证技术,使用了 Basic 认证。在服务消费过程中,客户端会使用 Basic 认证对服务请求进行认证,服务端会验证认证来确保请求的安全性。
本文转载自微信公众号「哪吒编程」,可以通过以下二维码关注。转载本文请联系哪吒编程公众号。

我正在尝试使用ruby和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我
我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..
最近,当我启动我的Rails服务器时,我收到了一长串警告。虽然它不影响我的应用程序,但我想知道如何解决这些警告。我的估计是imagemagick以某种方式被调用了两次?当我在警告前后检查我的git日志时。我想知道如何解决这个问题。-bcrypt-ruby(3.1.2)-better_errors(1.0.1)+bcrypt(3.1.7)+bcrypt-ruby(3.1.5)-bcrypt(>=3.1.3)+better_errors(1.1.0)bcrypt和imagemagick有关系吗?/Users/rbchris/.rbenv/versions/2.0.0-p247/lib/ru
在Rails4.0.2中,我使用s3_direct_upload和aws-sdkgems直接为s3存储桶上传文件。在开发环境中它工作正常,但在生产环境中它会抛出如下错误,ActionView::Template::Error(noimplicitconversionofnilintoString)在View中,create_cv_url,:id=>"s3_uploader",:key=>"cv_uploads/{unique_id}/${filename}",:key_starts_with=>"cv_uploads/",:callback_param=>"cv[direct_uplo
我想在Ruby中创建一个用于开发目的的极其简单的Web服务器(不,不想使用现成的解决方案)。代码如下:#!/usr/bin/rubyrequire'socket'server=TCPServer.new('127.0.0.1',8080)whileconnection=server.acceptheaders=[]length=0whileline=connection.getsheaders想法是从命令行运行这个脚本,提供另一个脚本,它将在其标准输入上获取请求,并在其标准输出上返回完整的响应。到目前为止一切顺利,但事实证明这真的很脆弱,因为它在第二个请求上中断并出现错误:/usr/b
您如何在Rails中的实时服务器上进行有效调试,无论是在测试版/生产服务器上?我试过直接在服务器上修改文件,然后重启应用,但是修改好像没有生效,或者需要很长时间(缓存?)我也试过在本地做“脚本/服务器生产”,但是那很慢另一种选择是编码和部署,但效率很低。有人对他们如何有效地做到这一点有任何见解吗? 最佳答案 我会回答你的问题,即使我不同意这种热修补服务器代码的方式:)首先,你真的确定你已经重启了服务器吗?您可以通过跟踪日志文件来检查它。您更改的代码显示的View可能会被缓存。缓存页面位于tmp/cache文件夹下。您可以尝试手动删除
require"socket"server="irc.rizon.net"port="6667"nick="RubyIRCBot"channel="#0x40"s=TCPSocket.open(server,port)s.print("USERTesting",0)s.print("NICK#{nick}",0)s.print("JOIN#{channel}",0)这个IRC机器人没有连接到IRC服务器,我做错了什么? 最佳答案 失败并显示此消息::irc.shakeababy.net461*USER:Notenoughparame
我有一个使用PDFKit呈现网页的pdf版本的Rails应用程序。我使用Thin作为开发服务器。问题是当我处于开发模式时。当我使用“bundleexecrailss”启动我的服务器并尝试呈现任何PDF时,整个过程会陷入僵局,因为当您呈现PDF时,会向服务器请求一些额外的资源,如图像和css,看起来只有一个线程.如何配置Rails开发服务器以运行多个工作线程?非常感谢。 最佳答案 我找到的最简单的解决方案是unicorn.geminstallunicorn创建一个unicorn.conf:worker_processes3然后使用它:
关于如何使用git设置类似Dropbox的服务,您有什么建议吗?您认为git是解决此问题的合适工具吗?我在考虑使用git+rush解决方案,你觉得怎么样? 最佳答案 检查这个开源项目:https://github.com/hbons/SparkleShare来自项目的自述文件:Howdoesitwork?SparkleSharecreatesaspecialfolderonyourcomputer.Youcanaddremotelyhostedfolders(or"projects")tothisfolder.Theseprojec
我将以下代码放在一起用于一个简单的RubyTFTP服务器。它工作正常,因为它监听端口69并且我的TFTP客户端连接到它,我能够将数据包写入test.txt,但我不只是写入数据包,我希望能够从我的客户端通过TFTP传输文件到/temp目录。预先感谢您的帮助!require'socket.so'classTFTPServerdefinitialize(port)@port=portenddefstart@socket=UDPSocket.new@socket.bind('',@port)whiletruepacket=@socket.recvfrom(1024)putspacketFile