предисловие
Будучи высокопроизводительной инфраструктурой 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, который отвечает за представление этой реализации как службы. Процесс выглядит следующим образом:
Комбинируя приведенный выше рисунок, мы можем сказать, что на стороне провайдера процесс предоставления услуги выглядит следующим образом:
первый,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;
}
}