Краткий обзор процесса вызова Dubbo

Java

предисловие

Будучи высокопроизводительной инфраструктурой Java RPC, Apache Dubbo играет очень важную роль в развитии внутренней системы обслуживания и широко используется большим количеством компаний.

С приближением Нового года у некоторых друзей может появиться идея искать новые возможности, поэтому в процессе собеседования часто можно встретить такой вопрос:

Вы знаете Dubbo? Можете ли вы рассказать о процессе его вызова?

Для тех, кто его не знает, он, несомненно, снизит оценку впечатления, если его только использовать, этого недостаточно, по крайней мере, мы должны понимать его основные принципы.

С точки зрения пользователей Dubbo, эта статья пытается связать соответствующие точки знаний с блок-схемами и ключевыми кодами, чтобы ответить на наши вопросы выше.

1. Поставщики услуг

С точки зрения разработчика программы, в первую очередь у нас должны быть поставщики услуг. Обычно мы отмечаем реализацию Dubbo на реализации конкретного интерфейса.Serviceаннотация.

package com.viewscenes.producer.dubbo;
import org.apache.dubbo.config.annotation.Service;
import com.viewscenes.common.service.DubboUserService;
@Service
public class DubboUserServiceImpl implements DubboUserService {
}

Соответствующий класс синтаксического анализа этого класса реализации в Dubbo:ServiceBean, который отвечает за представление этой реализации как службы. Процесс выглядит следующим образом:

Dubbo服务暴露过程

Комбинируя приведенный выше рисунок, мы можем сказать, что на стороне провайдера процесс предоставления услуги выглядит следующим образом:

первый,ServiceConfigКласс относится к ссылке класса реализации, которая предоставляет услуги внешнему миру (например,DubboUserServiceImpl), а затем передатьProxyFactotyРасширение интерфейса реализует классgetInvoker()метод использует ref для созданияAbstractProxyInvokerНапример, это завершает конкретную службу дляInvokerтрансформация.

Далее через протокол Dubboexport()метод, будетInvokerпревратиться вExporter. Тогда здесь он начнется первымNetty Server, а затем зарегистрируйте службу в реестре служб.

Здесь мы должны отметить, что в качестве поставщика услуг мониторинг TCP-порта был открыт через Netty. Затем, когда потребитель вызывает через ряд процессоров Netty Handler, он вызываетDubboProtocol > ExchangeHandler.reply().

В этом методе происходит обратный процесс. Найдите имя вызываемого интерфейса службыExporter, а затем получитьInvokerобъект.

Invoker<?> getInvoker(Channel channel, Invocation inv) throws RemotingException {
    int port = channel.getLocalAddress().getPort();
    String path = inv.getAttachments().get(PATH_KEY);
    String serviceKey = serviceKey(port, path, inv.getAttachments().get(VERSION_KEY),  inv.getAttachments().get(GROUP_KEY));
    DubboExporter<?> exporter = (DubboExporter<?>) exporterMap.get(serviceKey);
    return exporter.getInvoker();
}

Из вышеприведенного анализа мы уже знаем, чтоInvokerОбъект генерируется из класса реализации службы.AbstractProxyInvokerпример. в конечном итоге это вызоветwrapper.invokeMethod()метод. здесьwrapperкласс пройденJavassistСгенерированный класс в памяти, его основной метод выглядит так:

Dubboсоздаст реализацию для каждого поставщика услугWrapperДобрый. После получения запроса потребителя, в соответствии с переданным именем метода и параметрами,WrapperКласс может вызвать реализацию класса интерфейса поставщика услуг. Цель этого в основном состоит в том, чтобы уменьшить вызов рефлексии.

2. Потребители услуг

На стороне потребителя сервиса мы можем напрямую ссылаться на интерфейс.

@Reference
DubboUserService userService;

Может быть вы спросите, а зачем только вводить такой общий интерфейс, можно вызывать удаленную службу?

мы думаем оКакова связь между интерфейсом Dao в Mybatis и SQL в файле XML?Как они связаны в этом вопросе?

Грубо говоря, до сих порSpringкредит илиSpring FactoryBeanкредит.

существуетDubbo, отмечено@Referenceинтерфейс, будет рассматриваться какFactory Bean, этот компонент обычно возвращает прокси-объект для защиты некоторых сложных операций внизу. НапримерMybatisИнтерфейс картографа связан с файлом xml,Dubboсетевое общение и т.д.

Давайте сначала посмотрим на конкретный процесс со стороны потребителя через картинку:

服务引用

В сочетании с приведенным выше рисунком мы резюмируем процесс обращения к службе:

ReferenceаннотированныйDubboинтерфейс, будет зарегистрирован какFactoryBeanи, наконец, возвращает прокси-объект.

В процессе создания прокси вызываются другие методы сборки и слиянияInvokerпример.

Во-первых, позвонитеDubboProtocolМетод refer возвращаетDubboInvokerобъект. Здесь важнее получить экземпляр клиента. НапримерNettyClient,DubboЧтобы полагаться на него для сетевого общения.

Затем также необходимо объединить несколько экземпляров поставщика услуг в один, что является реализацией механизма отказоустойчивости кластера.

Наконец, поJavassistProxyFactoryСоздайте прокси и вернитесь. Здесь его процессорInvokerInvocationHandler, что означает, что когда мы вызываемDubboКогда интерфейс используется, он фактически вызываетInvokerInvocationHandler.invoke()метод, здесьDubboВыполнен ряд действий, таких как отказоустойчивость кластера, балансировка нагрузки и вызов удаленных методов.

Когда потребитель Dubbo отправляет запрос, он в конечном итоге вызываетDubboInvokerметод в . Здесь будет завершена конкретная логика запроса, например, отправка данных запроса.

final class HeaderExchangeChannel implements ExchangeChannel {
    //创建请求消息对象
    Request req = new Request();
    req.setVersion(Version.getProtocolVersion());
    req.setTwoWay(true);
    req.setData(request);
    
    //创建Future,用于获取返回结果
    DefaultFuture future = DefaultFuture.newFuture(this.channel, req, timeout, executor);
    try {
        //通过Netty客户端发送数据
        this.channel.send(req);
        return future;
    } catch (RemotingException var7) {
    	future.cancel();
    	throw var7;
    }
}

3. Процесс запрос-ответ

Dubbo请求响应过程