предисловие
это конец集群容错
и服务发布原理
После этих двух небольших тем друг спросил меня服务引用
Когда это начнется, эта статья服务引用
Просветительская статья.Я смотрел исходный код с вами раньше, в видуTalk is cheap.Show me your code
, так что эта статья будет писать код вместе с вами.
Вопросы для интервью в прямом эфире
-
В чем принцип даббо?Пожалуйста, расскажите кратко
-
Рассматривали ли вы возможность самостоятельно реализовать инфраструктуру RPC, аналогичную dubbo, и если да, хотели бы вы ее реализовать?
(面试高频题,区分度高)
-
Вы сказали, что использовали mybatis, так знаете ли вы принцип работы интерфейса Mapper? (Если ответ хороший, и упоминается ключевое слово dynamic proxy, вы будете продолжать спрашивать, а как динамический прокси инъектирует в Mapper интерфейс через зависимости?Сукно?)
Сразу к делу
простой принцип
Когда дело доходит до принципа даббо, мы должны сначала знать, что основная концепция даббо, с точки зрения непрофессионала, заключается в том, что даббо делает.
dubbo — это инфраструктура распределенных сервисов, предназначенная для предоставления высокопроизводительных и прозрачных решений удаленного вызова RPC-сервисов, а также решений для управления сервисами SOA.
Перед этим необходимо рассказать о следующих простых и запутанных понятиях
- кластер
Тот же бизнес, развернутый на нескольких серверах
- распределенный
Бизнес разделен на несколько подбизнесов и развернут на разных серверах.
- RPC
RPC (протокол удаленного вызова процедур) --- удаленный вызов процедур
Мы фиксируем несколько важных ключевых слов,分布式
,透明化
,RPC
.
Поскольку каждая служба развернута на разных серверах, вызов между службами осуществляется для связи через сеть.Простая схема описывается следующим образом:
Перед [анализом исходного кода dubbo - локальное воздействие] многие друзья оставили сообщение, спрашивая, в чем польза от этого локального воздействия Прежде всего, как широко используемая структура, производительность dubbo улучшается понемногу, поэтому бенефициары все большое количество. Вот почему исходный код JDK нравится использовать位运算
.Как на картинкеUserService
иRoleService
Сервисы находятся в одном модуле, и их прямая связь через JVM определенно намного лучше, чем связь через сеть, поэтому dubbo спроектирован так, чтобы иметь и то, и другое.远程暴露
, и本地暴露
причина.
Поскольку задействована сетевая связь, очевидно, что очень недружелюбно писать различные сетевые запросы, кодеки и другие связанные коды до того, как потребители услуг вызовут услуги.透明
, Смысл, пусть звонящий в сеть запросит, детали кодеков вроде прозрачны, пусть будет так же, как звонит локальная служба, звонит удаленная служба, даже не чувствуется звонок в удаленную службу.
Сказав так много, как это сделать?Чтобы выполнить это требование, мы можем легко придумать ключевое слово, то есть динамический прокси
public interface MenuService {
void sayHello();
}
public class MenuServiceImpl implements MenuService{
@Override
public void sayHello() {
}
}
public class ProxyFactory implements InvocationHandler {
private Class interfaceClass;
public ProxyFactory(Class interfaceClass) {
this.interfaceClass = interfaceClass;
}
//返回代理对象,此处用泛型为了调用时不用强转,用Object需要强转
public <T> T getProxyObject(){
return (T) Proxy.newProxyInstance(this.getClass().getClassLoader(),//类加载器
new Class[]{interfaceClass},//为哪些接口做代理(拦截哪些方法)
this);//(把这些方法拦截到哪处理)
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println(method);
System.out.println("进行编码");
System.out.println("发送网络请求");
System.out.println("将网络请求结果进行解码并返回");
return null;
}
}
public void test() throws Exception {
ProxyFactory proxyFactor = new ProxyFactory(MenuService.class);
MenuService menuService = proxyFactor.getProxyObject();
menuService.sayHello();
//输出结果如下:
//public abstract void com.toby.rpc.MenuService.sayHello()
//进行编码
//发送网络请求
//将网络请求结果进行解码并返回
}
Здесь могут быть друзья, которые захотят пожаловаться, я несколько месяцев читал ваш анализ исходного кода, я уже понял, что вы сказали выше, поэтому я все еще обращаю на это внимание.肥朝公众号
Почему.Что я хочу так это построить фреймворк похожий на dubbo,производительность почти ок,по крайней мере внешний вид и использование похожи,например когда мы обычно используем dubbo,мы сначала настраиваем такую штуку в конфигурационном файле
<dubbo:reference id="demoService" interface="com.alibaba.dubbo.demo.DemoService"/>
затем используйте@Autowired
Внедрение зависимостей используется, грубо говоря, обязательно!
Слияние с весной
Если мы хотим написать простой RPC, назовем егоtobyRPC
(английское имя Фей Чао - toby), на самом деле лично я предпочитаю скриншоты, но мы с некоторыми друзьями неоднократно подчеркивали код, потом я вставлю код сюда
1. Разработка свойств конфигурации и JavaBeans
public class ReferenceBean<T> extends ReferenceConfig<T> implements FactoryBean {
@Override
public Object getObject() throws Exception {
return get();
}
@Override
public Class<?> getObjectType() {
return getInterfaceClass();
}
@Override
public boolean isSingleton() {
return true;
}
}
public class ReferenceConfig<T> {
private Class<?> interfaceClass;
// 接口代理类引用
private transient volatile T ref;
public synchronized T get() {
if (ref == null) {
init();
}
return ref;
}
private void init() {
ref = new ProxyFactory(interfaceClass).getProxyObject();
}
public Class<?> getInterfaceClass() {
return interfaceClass;
}
public void setInterfaceClass(Class<?> interfaceClass) {
this.interfaceClass = interfaceClass;
}
}
2. Запишите файл XSD
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xsd:schema
xmlns="http://toby.com/schema/tobyRPC"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:tool="http://www.springframework.org/schema/tool"
targetNamespace="http://toby.com/schema/tobyRPC">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace"/>
<xsd:import namespace="http://www.springframework.org/schema/beans"/>
<xsd:import namespace="http://www.springframework.org/schema/tool"/>
<xsd:complexType name="referenceType">
<xsd:complexContent>
<xsd:extension base="beans:identifiedType">
<xsd:attribute name="interface" type="xsd:token" use="required">
<xsd:annotation>
<xsd:documentation><![CDATA[ The service interface class name. ]]></xsd:documentation>
<xsd:appinfo>
<tool:annotation>
<tool:expected-type type="java.lang.Class"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:element name="reference" type="referenceType">
<xsd:annotation>
<xsd:documentation><![CDATA[ Reference service config ]]></xsd:documentation>
</xsd:annotation>
</xsd:element>
</xsd:schema>
3. ПишитеNamespaceHandler
иBeanDefinitionParser
Полная аналитическая работа
public class TobyRPCBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {
protected Class getBeanClass(Element element) {
return ReferenceBean.class;
}
protected void doParse(Element element, BeanDefinitionBuilder bean) {
String interfaceClass = element.getAttribute("interface");
if (StringUtils.hasText(interfaceClass)) {
bean.addPropertyValue("interfaceClass", interfaceClass);
}
}
}
public class TobyRPCNamespaceHandler extends NamespaceHandlerSupport {
public void init() {
registerBeanDefinitionParser("reference", new TobyRPCBeanDefinitionParser());
}
}
4. Пишитеspring.handlers
иspring.schemas
Соедините все детали последовательно
spring.handlers
http\://toby.com/schema/tobyRPC=com.toby.config.TobyRPCNamespaceHandler
spring.schemas
http\://toby.com/schema/tobyRPC.xsd=META-INF/tobyRPC.xsd
5. Создайте файл конфигурации
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tobyRPC="http://toby.com/schema/tobyRPC"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://toby.com/schema/tobyRPC http://toby.com/schema/tobyRPC.xsd">
<tobyRPC:reference id="menuService" interface="com.toby.rpc.MenuService" />
</beans>
Скриншот демонстрационной структуры выглядит следующим образом:
Все готово, давайте запустим модульный тест, чтобы увидеть
Результаты работы, как мы и ожидали, но конкретно, как кодировать, как отправить запрос, но не сказал, как декодировать, кажется, ах. Не сказал? Я не сказал это правильно в конце服务引用
После этой небольшой темы я сосредоточусь на том, чтобы взглянуть на даббо вместе с вами.编解码
,spi
,javassist
Дождитесь исходников ключевого контента, и после того, как вы примерно усвоили идею всего фреймворка, затем скопируйте простенький фреймворк dubbo со всеми внутренними органами (включая паттерны проектирования, проектирование архитектуры dubbo).
Стук по доске
Почему в интервью любят задавать принцип, это все для того, чтобы притвориться? Конечно нет, я понимаю принцип, многие вещи все-в-одном. Давайте посмотрим на этот вопрос интервью mybatis. Прежде всего, принцип интерфейса Mapper, вы можете обратиться к моему предыдущему изГрафический исходный код | Принцип сопоставления MyBatis, По сути, если говорить прямо, то это внедрить прокси-объект в интерфейс Mapper, и тогда метод вызова динамического прокси-объекта будет перехваченinvoke
, то в этомinvoke
В методе творятся какие-то неописуемые вещи(старый драйвер может YY сколько хочет) Суть всего этого в молчаливом инжекте динамического прокси объекта.На самом деле принцип инъекций тот же что и у dubbo , мы просто смотрим на две картинки