Comenzando con Dubbo, este es suficiente

1. La evolución de la arquitectura de software

El desarrollo de la arquitectura de software ha experimentado el proceso de evolución desde la arquitectura monolítica, la arquitectura vertical, la arquitectura SOA hasta la arquitectura de microservicios. Echemos un vistazo a estas arquitecturas por separado.

1.1 Arquitectura monolítica

Descripción de la arquitectura:

Todas las funciones se concentran en un solo proyecto (All in one).

Ventajas de la arquitectura:

La estructura es simple, el costo de desarrollo inicial es bajo y el ciclo de desarrollo es corto, lo que es adecuado para proyectos pequeños.

Desventajas arquitectónicas:

Todas las funciones están integradas en un proyecto, que no es fácil de desarrollar, expandir y mantener para proyectos a gran escala.

La pila de tecnología es limitada y solo se puede desarrollar en un idioma.

La expansión del rendimiento del sistema solo se puede realizar mediante la expansión de los nodos del clúster, lo cual es costoso.

1.2 Arquitectura vertical

Descripción de la arquitectura:

Corte según negocio para formar pequeños proyectos individuales.

Ventajas de la arquitectura:

La pila de tecnología es extensible (diferentes sistemas pueden escribirse en diferentes lenguajes de programación).

Desventajas arquitectónicas:

Las funciones se concentran en un proyecto, lo que no es propicio para el desarrollo, la expansión y el mantenimiento.

La expansión del sistema solo se puede realizar a través de clústeres.

Redundancia de funciones, redundancia de datos y fuerte acoplamiento entre proyectos.

1.3 Arquitectura SOA

El nombre completo de SOA es Arquitectura Orientada a Servicios, es decir, arquitectura orientada a servicios. Puede implementar, combinar y utilizar componentes de aplicación (servicios) de granularidad gruesa acoplados libremente de forma distribuida a través de la red de acuerdo con los requisitos. Un servicio generalmente existe como una forma separada en el proceso del sistema operativo.

Desde un punto de vista funcional, abstraiga la lógica comercial en servicios reutilizables y realice una rápida regeneración comercial a través de la orquestación de servicios. El propósito es transformar las funciones comerciales inherentes originales en servicios comerciales generales y lograr una rápida reutilización de la lógica comercial.

Descripción de la arquitectura:

Extraiga funciones o módulos repetitivos en componentes para proporcionar servicios externos y utilice la forma de ESB (Enterprise Service Bus) como puente para la comunicación entre proyectos y servicios.

Ventajas de la arquitectura:

Las funciones o módulos duplicados se extraen como servicios para mejorar la eficiencia del desarrollo.

Alta reutilización.

Alta mantenibilidad.

Desventajas arquitectónicas:

Los negocios son diferentes entre sistemas, y es difícil confirmar que funciones o módulos estén duplicados.

La granularidad del servicio de extracción es grande.

Existe un alto grado de acoplamiento entre sistemas y servicios.

1.4 Arquitectura de microservicios

 Descripción de la arquitectura:

La capa de servicio del sistema es completamente independiente y se extrae en microservicios uno por uno.

La granularidad de extracción es más fina y sigue un único principio.

Se transmite mediante un protocolo de trama ligero.

Ventajas de la arquitectura:

La granularidad de la división del servicio es más fina, lo que conduce a mejorar la eficiencia del desarrollo.

Se pueden formular esquemas de optimización correspondientes para diferentes servicios.

Aplicable a la era de Internet, el ciclo de iteración del producto es más corto.

Desventajas arquitectónicas:

Demasiado fino da como resultado demasiados servicios y altos costos de mantenimiento.

El costo técnico del desarrollo de sistemas distribuidos es alto y el desafío para el equipo es grande.

2. Descripción general de Apache Dubbo

2.1 Introducción a Dubbo

Apache Dubbo es un marco Java RPC de alto rendimiento. Su predecesor es un marco Java RPC de código abierto, ligero y de alto rendimiento de código abierto de Alibaba, que se puede integrar perfectamente con el marco Spring.

¿Qué es RPC?

El nombre completo de RPC es llamada a procedimiento remoto, es decir, llamada a procedimiento remoto . Por ejemplo, dos servidores A y B, una aplicación se implementa en el servidor A y una aplicación se implementa en el servidor B. La aplicación en el servidor A desea llamar al método proporcionado por la aplicación en el servidor B. Dado que las dos aplicaciones no están en el mismo espacio de memoria, no se pueden llamar directamente, por lo que es necesario expresar la semántica de la llamada y transmitir los datos de la llamada a través de la red.

Cabe señalar que RPC no es una tecnología específica, sino que se refiere a todo el proceso de llamada remota de la red.

RPC es un concepto generalizado, estrictamente hablando, todos los métodos de llamada a procedimientos remotos pertenecen a la categoría RPC. Varios lenguajes de desarrollo tienen sus propios marcos RPC. Hay muchos marcos RPC en Java, RMI, Hessian, Dubbo, etc. son ampliamente utilizados.

Dirección del sitio web oficial de Dubbo: https://dubbo.apache.org/zh/

Dubbo proporciona seis capacidades principales: llamadas RPC de alto rendimiento para proxy de interfaz, tolerancia inteligente a fallas y balanceo de carga, registro y descubrimiento de servicios automáticos, alta escalabilidad, programación de tráfico en tiempo de ejecución y gobierno, operación y mantenimiento de servicios visuales.

2.2 Arquitectura Dubbo

El diagrama de arquitectura de Dubbo (proporcionado oficialmente por Dubbo) es el siguiente:

 Descripción del rol del nodo:

nodo Nombre de rol
Proveedor El proveedor de servicios que expone el servicio.
Consumidor Consumidor del servicio llamando al servicio remoto
Registro Registro para Registro y Descubrimiento de Servicios
Monitor Un centro de monitoreo que cuenta las llamadas de servicio y los tiempos de llamada
Envase contenedor de ejecución de servicio

Las líneas discontinuas son todos los accesos asíncronos, y las líneas continuas son todos los accesos síncronos Líneas discontinuas moradas: funciones completadas al inicio Las líneas discontinuas azules (líneas continuas) son todas las funciones que se ejecutan durante la operación del programa.

Descripción de la relación de llamada:

  1. El contenedor de servicios es responsable de iniciar, cargar y ejecutar el proveedor de servicios.

  2. Cuando el proveedor de servicios se inicia, registra el servicio que proporciona con el registro.

  3. Cuando se inicia un consumidor de servicios, se suscribe al registro de los servicios que necesita.

  4. El registro devuelve la lista de direcciones del proveedor de servicios al consumidor. Si hay un cambio, el registro enviará los datos del cambio al consumidor en función de la conexión persistente.

  5. El consumidor del servicio, de la lista de direcciones de proveedores, selecciona un proveedor para llamar en función del algoritmo de equilibrio de carga suave y, si la llamada falla, selecciona otro para llamar.

  6. Los consumidores y proveedores de servicios acumulan la cantidad de llamadas y la duración de las llamadas en la memoria y envían regularmente datos estadísticos al centro de monitoreo cada minuto.

3. Servicio de registro Zookeeper

Como se puede ver en el diagrama de arquitectura Dubbo anterior, el Registro (registro de servicios) juega un papel vital en él. Dubbo recomienda oficialmente usar Zookeeper como registro de servicios.

3.1 Introducción a Zookeeper

Zookeeper es un subproyecto de Apache Hadoop. Es un servicio de directorio de tipo árbol que admite cambio push. Es adecuado como registro para los servicios de Dubbo. Tiene una alta potencia industrial y se puede utilizar en entornos de producción y se recomienda.

Para comprender el servicio de directorio en árbol de Zookeeper, echemos un vistazo al sistema de archivos de nuestra computadora (también una estructura de directorio en árbol):

Mi computadora se puede dividir en varias letras de unidad (como C, D, E, etc.), se pueden crear varios directorios debajo de cada letra de unidad, se pueden crear archivos debajo de cada directorio y también se pueden crear subdirectorios, lo que finalmente constituye una estructura tipo árbol. A través de este directorio con estructura de árbol, podemos almacenar archivos en diferentes categorías, lo cual es conveniente para que podamos encontrarlo más adelante. Y cada archivo en el disco tiene una ruta de acceso única, por ejemplo: C:\Windows\itcast\hello.txt.

Servicio de directorio del árbol Zookeeper:

Descripción del flujo:

  • Cuando se inicia el proveedor de servicios (Proveedor): escriba su propia dirección URL en el /dubbo/com.foo.BarService/providersdirectorio

  • Cuando se inicia el consumidor del servicio (Consumidor): Suscríbase a la dirección URL del proveedor en el /dubbo/com.foo.BarService/providersdirectorio . y escriba su propia dirección URL en el /dubbo/com.foo.BarService/consumersdirectorio

  • Cuando se inicia Monitor Center (Monitor): suscríbase a todas las direcciones URL de proveedores y consumidores en el /dubbo/com.foo.BarServicedirectorio

3.2 Instalar Zookeeper

Dirección de descarga: Índice de /dist/zookeeper

La versión de Zookeeper utilizada en este curso es 3.4.6. Una vez completada la descarga, se puede obtener un archivo comprimido llamado zookeeper-3.4.6.tar.gz.

Pasos de instalación:

El primer paso: instalar jdk (omitido)

Paso 2: Cargue el paquete comprimido zookeeper (zookeeper-3.4.6.tar.gz) al sistema Linux

Paso 3: Descomprima el paquete comprimido
                ​tar -zxvf zookeeper-3.4.6.tar.gz

Paso 4: ingrese al directorio zookeeper-3.4.6 y cree un directorio de datos
                ​mkdir data

Paso 5: ingrese al directorio conf y cambie el nombre de zoo_sample.cfg a zoo.cfg
                ​cd conf
                ​mv zoo_sample.cfg zoo.cfg

Paso 6: abra el archivo zoo.cfg y modifique el atributo de datos
                dataDir=/root/zookeeper-3.4.6/data

3.3 Iniciar y detener Zookeeper

Ingrese al directorio bin de Zookeeper e inicie el comando de servicio ./zkServer.sh start

Detener comando de servicio./zkServer.sh detener

Verifique el estado del servicio: ./zkServer.sh status

4. Inicio rápido de Dubbo

Como marco RPC, la función central de Dubbo es implementar llamadas remotas a través de la red. Esta sección es para crear dos aplicaciones, una como proveedor de servicios y otra como consumidor de servicios. Utilice Dubbo para implementar el método para que el consumidor del servicio llame de forma remota al proveedor del servicio.

4.1 Desarrollo de proveedores de servicios

Pasos de desarrollo:

(1) Cree un proyecto maven (empaquetado como war) dubbodemo_provider e importe las siguientes coordenadas en el archivo pom.xml

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
    <spring.version>5.0.5.RELEASE</spring.version>
</properties>
<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aspects</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jms</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <!-- dubbo相关 -->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>dubbo</artifactId>
        <version>2.6.0</version>
    </dependency>
    <dependency>
        <groupId>org.apache.zookeeper</groupId>
        <artifactId>zookeeper</artifactId>
        <version>3.4.7</version>
    </dependency>
    <dependency>
        <groupId>com.github.sgroschupf</groupId>
        <artifactId>zkclient</artifactId>
        <version>0.1</version>
    </dependency>
    <dependency>
        <groupId>javassist</groupId>
        <artifactId>javassist</artifactId>
        <version>3.12.1.GA</version>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>1.2.47</version>
    </dependency>
</dependencies>
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>2.3.2</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.apache.tomcat.maven</groupId>
            <artifactId>tomcat7-maven-plugin</artifactId>
            <configuration>
                <!-- 指定端口 -->
                <port>8081</port>
                <!-- 请求路径 -->
                <path>/</path>
            </configuration>
            <version>2.2</version>
        </plugin>
    </plugins>
</build>

(2) Configurar el archivo web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <display-name>Archetype Created Web Application</display-name>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext*.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
</web-app>

(3) Crear una interfaz de servicio

package com.itterence.service;

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

(4) Crear una clase de implementación de servicio

package com.itterence.service.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.itterence.service.HelloService;

@Service
public class HelloServiceImpl implements HelloService {
  public String sayHello(String name) {
    return "hello " + name;
   }
}

Nota: Dubbo proporciona la anotación de servicio utilizada en la clase de implementación del servicio y se utiliza para publicar servicios externamente.

(5) Cree applicationContext-service.xml en src/main/resources

<?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:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/mvc
            http://www.springframework.org/schema/mvc/spring-mvc.xsd
            http://code.alibabatech.com/schema/dubbo
            http://code.alibabatech.com/schema/dubbo/dubbo.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context.xsd">
    <!-- 当前应用名称,用于注册中心计算应用间依赖关系,注意:消费者和提供者应用名不要一样 -->
    <dubbo:application name="dubbodemo_provider"/>
    <!-- 连接服务注册中心zookeeper ip为zookeeper所在服务器的ip地址-->
    <dubbo:registry address="zookeeper://192.168.1.105:2181"/>
    <!-- 注册  协议和port  端口默认是20880 -->
    <dubbo:protocol name="dubbo" port="20881"></dubbo:protocol>
    <!-- 扫描指定包,加入@Service注解的类会被发布为服务  -->
    <dubbo:annotation package="com.itterence.service.impl"/>
</beans>

(6) Iniciar el servicio

tomcat7:ejecutar

4.2 Desarrollo del Consumidor de Servicios

Pasos de desarrollo:

(1) Cree un proyecto maven (empaquetado como war) dubbodemo_consumer, la configuración pom.xml es la misma que la del proveedor de servicios anterior, simplemente cambie el número de puerto del complemento Tomcat a 8082

(2) Configurar el archivo web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <display-name>Archetype Created Web Application</display-name>
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!-- 指定加载的配置文件 ,通过参数contextConfigLocation加载 -->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:applicationContext-web.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>
</web-app>

(3) Copie la interfaz HelloService en el proyecto del proveedor de servicios al proyecto actual

(4) Controlador de escritura

package com.itterence.controller;

import com.alibaba.dubbo.config.annotation.Reference;
import com.itterence.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;
    }
}

Nota: la anotación @Reference proporcionada por Dubbo se usa para inyectar HelloService en el controlador

(5) Cree applicationContext-web.xml en src/main/resources

<?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:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
      http://www.springframework.org/schema/beans/spring-beans.xsd
      http://www.springframework.org/schema/mvc
      http://www.springframework.org/schema/mvc/spring-mvc.xsd
      http://code.alibabatech.com/schema/dubbo
      http://code.alibabatech.com/schema/dubbo/dubbo.xsd
      http://www.springframework.org/schema/context
      http://www.springframework.org/schema/context/spring-context.xsd">
    <!-- 当前应用名称,用于注册中心计算应用间依赖关系,注意:消费者和提供者应用名不要一样 -->
    <dubbo:application name="dubbodemo-consumer"/>
    <!-- 连接服务注册中心zookeeper ip为zookeeper所在服务器的ip地址-->
    <dubbo:registry address="zookeeper://192.168.1.105:2181"/>
    <!-- 扫描的方式暴露接口  -->
    <dubbo:annotation package="com.itterence.controller"/>
</beans>

(6) Ejecutar la prueba

tomcat7:ejecutar inicio

Ingrese http://localhost:8082/demo/hello.do?name=Jack en el navegador para ver la salida del navegador

 Pensamiento 1: en el caso de la entrada de Dubbo anterior, copiamos la interfaz HelloService del proyecto del proveedor de servicios (dubbodemo_provider) al proyecto del consumidor de servicios (dubbodemo_consumer).¿Es apropiado? ¿Hay una mejor manera?

Respuesta: Obviamente, este enfoque no es bueno. La misma interfaz se copia dos veces, lo que no favorece el mantenimiento posterior. Una mejor manera es crear un proyecto maven separado y crear esta interfaz en este proyecto maven. Los proyectos que necesitan confiar en esta interfaz solo necesitan introducir coordenadas maven en el archivo pom.xml de sus propios proyectos.

Pensamiento 2: en el proyecto del consumidor de servicios (dubbodemo_consumer), solo se hace referencia a la interfaz HelloService y no se proporciona ninguna clase de implementación. ¿Cómo hace Dubbo llamadas remotas?

Respuesta: La capa inferior de Dubbo es crear un objeto proxy para la interfaz HelloService basada en tecnología proxy, y las llamadas remotas se completan a través de este objeto proxy. Puede ver la estructura interna de este objeto proxy a través de la función de depuración de la herramienta de desarrollo. Además, Dubbo realiza la capa inferior de transmisión de red basada en el marco Netty.

Pensamiento 3: En el caso de entrada de Dubbo anterior, usamos Zookeeper como registro de servicios. Los proveedores de servicios deben registrar su información de servicio con Zookeeper, y los consumidores de servicios deben suscribirse a los servicios que necesitan de Zookeeper. En este momento, el servicio Zookeeper se vuelve muy importante, ¿cómo prevenir el punto único de falla de Zookeeper?

Respuesta: Zookeeper en realidad admite el modo de clúster. Puede configurar el clúster de Zookeeper para lograr una alta disponibilidad del servicio de Zookeeper y evitar puntos únicos de falla.

5. Consola de administración de Dubbo

Cuando estamos desarrollando, necesitamos saber qué servicios están registrados en el registro de Zookeeper y qué consumidores están consumiendo estos servicios. Podemos hacer esto mediante la implementación de un centro de gestión. De hecho, el centro de gestión es una aplicación web que se puede implementar en tomcat.

5.1 Instalación

Pasos de instalación:

(1) Copie el archivo dubbo-admin-2.6.0.war de los datos en el directorio webapps de tomcat

(2) Inicie tomcat, el archivo war se descomprimirá automáticamente

(3) Modifique el archivo dubbo.properties en WEB-INF, tenga en cuenta que el valor correspondiente a dubbo.registry.address debe corresponder a la dirección IP y el número de puerto del Zookeeper utilizado actualmente

dubbo.registry.address=zookeeper://192.168.1.105:2181
dubbo.admin.root.password=root
dubbo.admin.guest.password=guest

(4) Reiniciar gato

5.2 Uso

Pasos:

(1) Visite http://localhost:8080/dubbo-admin-2.6.0/ e ingrese el nombre de usuario (raíz) y la contraseña (raíz)

(2) Inicie el proyecto del proveedor de servicios y el proyecto del consumidor de servicios, y puede ver la información correspondiente en

6. Instrucciones de configuración relacionadas con Dubbo

6.1 Escaneo de paquetes

<dubbo:annotation package="com.itterence.service" />

Tanto los proveedores de servicios como los consumidores de servicios deben configurarse, lo que indica el escaneo de paquetes, que se utiliza para escanear las clases en el paquete especificado (incluidos los subpaquetes).

Si no usa el escaneo de paquetes, también puede publicar servicios configurando de la siguiente manera:

<bean id="helloService" class="com.itterence.service.impl.HelloServiceImpl" />
<dubbo:service interface="com.itterence.api.HelloService" ref="helloService" />

Como consumidor de servicios, puede hacer referencia a los servicios configurando de la siguiente manera:

<!-- 生成远程服务代理,可以和本地bean一样使用helloService -->
<dubbo:reference id="helloService" interface="com.itterence.api.HelloService" />

Para publicar y hacer referencia a servicios en el método anterior, un elemento de configuración (dubbo:service, dubbo:reference) solo puede publicar o hacer referencia a un servicio. Si hay varios servicios, este método es más engorroso. Se recomienda el método de escaneo de paquetes.

6.2 Acuerdo

<dubbo:protocol name="dubbo" port="20880"/>

Generalmente configurado en el lado del proveedor de servicios, puede especificar el nombre del protocolo y el número de puerto que se utilizará.

Los protocolos soportados por Dubbo son: dubbo, rmi, hessian, http, webservice, rest, redis, etc.

Se recomienda utilizar el protocolo dubbo.

El protocolo dubbo utiliza una sola conexión larga y comunicación asíncrona NIO, que es adecuada para un volumen de datos pequeño y llamadas de servicio simultáneas grandes, y cuando la cantidad de máquinas consumidoras de servicios es mucho mayor que la cantidad de máquinas proveedoras de servicios. No es adecuado para servicios que transmiten grandes cantidades de datos, como transferencia de archivos, transferencia de video, etc., a menos que el volumen de solicitudes sea muy bajo.

También puede configurar múltiples protocolos en el mismo proyecto, y diferentes servicios pueden usar diferentes protocolos, por ejemplo:

<!-- 多协议配置 -->
<dubbo:protocol name="dubbo" port="20880" />
<dubbo:protocol name="rmi" port="1099" />
<!-- 使用dubbo协议暴露服务 -->
<dubbo:service interface="com.itterence.api.HelloService" ref="helloService" protocol="dubbo" />
<!-- 使用rmi协议暴露服务 -->
<dubbo:service interface="com.itterence.api.DemoService" ref="demoService" protocol="rmi" />

Si está utilizando el escaneo de paquetes, puede especificar el protocolo en la anotación @Service, por ejemplo: @Service(protocol="dubbo") 

6.3 Comprobación al inicio

<dubbo:consumer check="false"/>

La configuración anterior debe configurarse en el lado del consumidor del servicio.Si no está configurado, el valor de verificación predeterminado es verdadero. De manera predeterminada, Dubbo verificará si los servicios dependientes están disponibles al inicio. Si no está disponible, generará una excepción para evitar que se complete la inicialización de Spring, de modo que los problemas se puedan detectar temprano cuando se conecte. La verificación se puede desactivar cambiando el valor de verificación a falso.

Se recomienda establecer el valor de verificación en falso en la fase de desarrollo y en verdadero en el entorno de producción.

6.4 Equilibrio de carga

Load Balance (Balance de carga): De hecho, la solicitud se asigna a múltiples unidades de operación para su ejecución, a fin de completar la tarea de trabajo en conjunto.

Durante el balanceo de carga del clúster, Dubbo proporciona una variedad de estrategias de balanceo (que incluyen aleatorio, round robin, número mínimo de llamadas activas y hash consistente). El valor predeterminado es llamadas aleatorias.

Configure la estrategia de equilibrio de carga, que se puede configurar en el lado del proveedor de servicios o en el lado del consumidor de servicios, de la siguiente manera:

@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;
   }
}

El efecto de equilibrio de carga de Dubbo se puede observar iniciando múltiples proveedores de servicios.

Nota: Debido a que estamos iniciando múltiples proveedores de servicios en una máquina, debemos modificar el número de puerto de Tomcat y el número de puerto del servicio Dubbo para evitar conflictos de puertos.

En el entorno de producción real, se implementan múltiples proveedores de servicios en diferentes máquinas, por lo que no hay problema de conflicto de puertos.

7. Resuelva el problema de que Dubbo no puede publicar el Servicio que está representado por la transacción

Hemos completado el caso de entrada de Dubbo anteriormente. A través del caso de entrada, podemos ver que el escaneo de paquetes se puede realizar a través de la configuración de etiquetas proporcionada por Dubbo, y las clases anotadas con @Service se pueden publicar como servicios.

Pero si agregamos la anotación de control de transacciones @Transactional a la clase de proveedor de servicios, el servicio no se publicará correctamente. El motivo es que el principio subyacente del control de transacciones es crear un objeto proxy para la clase de proveedor de servicios. De forma predeterminada, Spring crea un objeto proxy basado en el método de proxy dinámico JDK, y el nombre de clase completo de este objeto proxy es com. sun.proxy.$Proxy42 (los últimos dos dígitos no son fijos), lo que provocó que Dubbo no pudiera completar la comparación al realizar la comparación de paquetes antes de publicar el servicio y, por lo tanto, no publicó el servicio.

7.1 Visualización de problemas

Demostrado sobre la base del proyecto del proveedor de servicios dubbodemo_provider del caso de entrada

Pasos:

(1) Agregar coordenadas maven al archivo pom.xml

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.47</version>
</dependency>
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.1.6</version>
</dependency>
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-spring</artifactId>
    <version>1.3.2</version>
</dependency>

(2) En el archivo de configuración applicationContext-service.xml, agregue la configuración relevante de la fuente de datos, el administrador de transacciones y la anotación de transacción abierta

<!--数据源-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
    <property name="username" value="root"/>
    <property name="password" value="646453"/>
    <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://192.168.1.105:3306/demo"/>
</bean>
<!-- 事务管理器  -->
<bean id="transactionManager"
      class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"/>
</bean>
<!--开启事务控制的注解支持-->
<tx:annotation-driven transaction-manager="transactionManager"/>

La base de datos conectada arriba puede ser creada por usted mismo

(3) Agregue la anotación @Transactional a la clase HelloServiceImpl

(4) Iniciar proveedores de servicios y consumidores de servicios, y acceder

El error anterior es que no hay ningún proveedor de servicios disponible

Verifique la consola de administración de dubbo y descubra que el servicio no se ha liberado, de la siguiente manera:

Puede ver el proceso de ejecución de Dubbo a través de la depuración de puntos de interrupción. Dubbo lo procesa a través del método postProcessAfterInitialization de AnnotationBean

7.2 Soluciones

A través de la depuración del punto de interrupción anterior, podemos ver que después de agregar la anotación de transacción a la clase HelloServiceImpl, Spring creará un objeto proxy para esta clase basado en la tecnología de proxy dinámico JDK. El nombre de clase completo del objeto proxy creado es com.sun. proxy.$Proxy 35. Como resultado, Dubbo no pudo hacer coincidir el paquete (porque el paquete que escaneamos al publicar el servicio era com.itterence.service), por lo que el código que realmente publicó el servicio no se ejecutó.

Pasos de solución:

(1) Modifique el archivo de configuración applicationContext-service.xml, especifique el atributo proxy-target-class cuando la compatibilidad con anotaciones de control de transacciones esté habilitada y el valor sea verdadero. Su función es utilizar el método proxy cglib para crear un objeto proxy para la clase de servicio.

<!--开启事务控制的注解支持-->
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>

(2) Modifique la clase HelloServiceImpl, agregue el atributo interfaceClass a la anotación del servicio, el valor es HelloService.class y la función es especificar el tipo de interfaz del servicio.

@Service(interfaceClass = HelloService.class)
@Transactional
public class HelloServiceImpl implements HelloService {
  public String sayHello(String name) {
    return "hello " + name;
   }
}

También debe modificarse aquí, de lo contrario, la interfaz del servicio publicado será SpringProxy en lugar de la interfaz HelloService, de la siguiente manera:

Supongo que te gusta

Origin blog.csdn.net/qq_39997939/article/details/123030622
Recomendado
Clasificación