Hi I’m Shendi
Introducción detallada a Dubbo, método API y método SpringBoot
He estado usando el marco RPC escrito por mí mismo antes, porque está escrito por mí mismo y su función no es tan buena como el marco de código abierto en el mercado, incluida la serie Spring Cloud más adelante. Si todavía lo escribo por mí mismo, Necesito hacer integración y cosas por el estilo. Gran carga de trabajo.
Basado en la idea de no hacer ruedas sin hacer ruedas, comencé a conocer Dubbo
dubbo
Apache Dubbo es un marco WEB y RPC fácil de usar y de alto rendimiento. También proporciona capacidades, herramientas y mejores prácticas para crear microservicios de nivel empresarial, como descubrimiento de servicios, control de tráfico, observabilidad y autenticación.
Los microservicios desarrollados con Dubbo tienen capacidades nativas de comunicación y descubrimiento de direcciones remotas entre sí. Al usar las ricas funciones de gobierno de servicios proporcionadas por Dubbo, se pueden cumplir las demandas de gobierno de servicios, como el descubrimiento de servicios, el equilibrio de carga y la programación del tráfico. Dubbo está diseñado para ser altamente escalable y los usuarios pueden implementar fácilmente varias lógicas personalizadas para la intercepción de tráfico y la selección de ubicación.
Documento oficial: https://cn.dubbo.apache.org/zh-cn/index.html
RPC, Distribuido, Microservicios
Aquí hay una breve introducción, RPC es Llamada de procedimiento remoto (Llamada de procedimiento remoto), a través de RPC, puede hacer que un programa llame a la función de otros programas de dispositivos (a través de la red)
Distribuido significa que múltiples programas se comunican a través de la red para formar un sistema, generalmente usando RPC para lograr
Los microservicios dividen un programa en varios programas y los programas se comunican de forma distribuida.
Inicio rápido
iniciar el cuidador del zoológico
Actualmente, Zookeeper se usa en documentos oficiales, por lo que primero debe instalarse Zookeeper. Para la instalación y el uso de Zookeeper, consulte este artículo.
Introducción detallada a la instalación de Zookeeper, fácil de usar
Desarrolle aplicaciones de microservicio basadas en la API de Dubbo
Cualquier proyecto de Maven, edite pom.xml
y agregue el siguiente contenido
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
<version>3.2.0-beta.4</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-x-discovery</artifactId>
<version>4.3.0</version>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.8.0</version>
<exclusions>
<exclusion>
<groupId>io.netty</groupId>
<artifactId>netty-handler</artifactId>
</exclusion>
<exclusion>
<groupId>io.netty</groupId>
<artifactId>netty-transport-native-epoll</artifactId>
</exclusion>
</exclusions>
</dependency>
Nota: la mayoría de los paquetes dependientes usan org.apache.dubbo
proveedor de servicio
Cree dos paquetes nuevos, una API, que contiene la definición de la interfaz de servicio, y un proveedor, que contiene la implementación específica de la interfaz de servicio.
Cree una nueva interfaz bajo el paquete api, el contenido es el siguiente
public interface ITest {
String sayHi(String name);
}
Cree una nueva clase en el paquete del proveedor para implementar esta interfaz y publique el servidor, el contenido es el siguiente
import org.apache.dubbo.config.ProtocolConfig;
import org.apache.dubbo.config.RegistryConfig;
import org.apache.dubbo.config.ServiceConfig;
import org.apache.dubbo.config.bootstrap.DubboBootstrap;
import demo.api.ITest;
public class Test implements ITest {
public static void main(String[] args) {
// 定义具体的服务
ServiceConfig<ITest> service = new ServiceConfig<>();
service.setInterface(ITest.class);
service.setRef(new Test());
// 启动 Dubbo
DubboBootstrap.getInstance()
.application("first-dubbo-provider")
.registry(new RegistryConfig("zookeeper://127.0.0.1:2181"))
.protocol(new ProtocolConfig("dubbo", -1))
.service(service)
.start()
.await();
}
public String sayHi(String name) {
return "hi, " + name;
}
}
El guardián del zoológico anterior es la dirección del guardián del zoológico, si se cambia la cadena sobre el puerto, debe cambiarse en consecuencia
Ahora se puede iniciar el proveedor de servicios y la consola generará mucha información después del inicio...
Espere un momento, si ve la siguiente información, significa que el inicio se realizó correctamente
Obtuve una respuesta de ping para la identificación de la sesión:…
Esta cosa se emitirá todo el tiempo, es el registro del mecanismo de latido del corazón de ZK
Describa brevemente las funciones implementadas anteriormente, que es equivalente a proporcionar una interfaz sayHi. La interfaz recibe un parámetro de nombre y devuelve una cadena. El contenido de la cadena es hola, + el parámetro de nombre pasado
consumidor de servicios
Crear un nuevo paquete client
para almacenar clientes (consumidores)
Cree una nueva clase Test2 en el paquete para suscribirse al servicio proporcionado y llamar
El contenido es el siguiente
import java.io.IOException;
import org.apache.dubbo.config.RegistryConfig;
import org.apache.dubbo.config.bootstrap.DubboBootstrap;
import com.alibaba.dubbo.config.ReferenceConfig;
import demo.api.ITest;
public class Test2 {
public static void main(String[] args) throws IOException {
ReferenceConfig<ITest> reference = new ReferenceConfig<>();
reference.setInterface(ITest.class);
DubboBootstrap.getInstance()
.application("first-dubbo-consumer")
.registry(new RegistryConfig("zookeeper://127.0.0.1:2181"))
.reference(reference);
ITest service = reference.get();
String message = service.sayHi("dubbo");
System.out.println("Receive result ======> " + message);
System.in.read();
}
}
Después de la ejecución, se emite una gran cantidad de información y, finalmente, se puede ver la siguiente información
De acuerdo con el código anterior, se implementa una llamada RPC simple a través del descubrimiento de servicios. El código es simple y básicamente puede saber lo que significa de un vistazo.
Desarrolle aplicaciones de microservicio basadas en SpringBoot
Similar al desarrollo de API, pero SpringBoot se caracteriza por un método de configuración basado en anotaciones, que permite un desarrollo rápido
El ejemplo del sitio web oficial es el uso de varios módulos Maven, hay tres módulos, respectivamente
- interfaz
- proveedor
- consumidor
En lo anterior, sabemos que tanto el proveedor como el consumidor necesitan definir la parte de la interfaz, el proveedor implementa la interfaz y el consumidor usa la interfaz.Para compartir la parte de la interfaz, el módulo múltiple utilizado en el ejemplo oficial
La IDEA utilizada por el ejemplo oficial, enumero el proceso de Eclipse aquí
(Por supuesto, también es posible no utilizar varios módulos, o se puede dividir en uno o dos proyectos)
Cree un nuevo proyecto Maven, seleccione pom para Packaging y agregue las siguientes dependencias a pom.xml
<properties>
<dubbo.version>3.2.0-beta.4</dubbo.version>
<spring-boot.version>2.7.8</spring-boot.version>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencyManagement>
<dependencies>
<!-- Spring Boot -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- Dubbo -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-bom</artifactId>
<version>${dubbo.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-dependencies-zookeeper-curator5</artifactId>
<version>${dubbo.version}</version>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
</plugin>
</plugins>
</pluginManagement>
</build>
Luego crea tres nuevos módulos, a saber
- consumidor de demostración (consumidor)
- proveedor de demostración (proveedor)
- interfaz de demostración (interfaz compartida)
Haga clic derecho en el proyecto -> Nuevo -> Otro -> Maven -> Módulo Maven
Packaging selecciona el tarro y crea un módulo
Cambie el contenido pom.xml de demo-provider y demo-consumer, copie el contenido requerido por SpringBoot y agregue las siguientes dependencias
<dependencies>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-samples-spring-boot-interface</artifactId>
<version>${project.parent.version}</version>
</dependency>
<!-- dubbo -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-dependencies-zookeeper-curator5</artifactId>
<type>pom</type>
<exclusions>
<exclusion>
<artifactId>slf4j-reload4j</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
<!-- spring boot starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
</dependencies>
Además de las dependencias anteriores, también es necesario introducir la parte común, interfaz de demostración
<dependency>
<groupId>demo-interface</groupId>
<artifactId>demo-interface</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
Publica una foto del proyecto.
Parte común (interfaz de demostración)
El módulo de interfaz de demostración es una parte común. Cree un nuevo paquete en src/main/java llamado demo y cree una nueva interfaz llamada Servicio en el paquete.
El comportamiento utilizado por el consumidor proveedor se define en el Servicio, el contenido es el siguiente
Debido a que este módulo solo necesita crear una interfaz, el pom básicamente no necesita introducir ninguna dependencia.
proveedor de servicios (proveedor de demostración)
Tanto los proveedores como los consumidores deben introducir partes comunes, como se mencionó anteriormente.
El módulo de proveedor de demostración es el proveedor, cree un nuevo paquete llamado demo.provider y cree una nueva clase bajo el paquete llamado ServerImpl
ServerImpl implementa el Servicio de interfaz proporcionado por la parte común (interfaz), de la siguiente manera
package demo.provider;
import org.apache.dubbo.config.annotation.DubboService;
import demo.Service;
@DubboService
public class ServiceImpl implements Service {
@Override
public String sayHi(String name) {
return "hi, " + name;
}
}
@DubboService
La diferencia con el desarrollo basado en API es que hay una anotación adicional en la clase
La anotación @DubboService es una anotación utilizada para marcar las interfaces del proveedor de servicios. La función de esta anotación es marcar una interfaz como proveedor de servicios de Dubbo, de modo que Dubbo pueda registrar y exponer la clase de implementación de la interfaz como un servicio al que pueden llamar otros servicios. La clase de implementación de interfaz marcada por la anotación @DubboService será escaneada por el marco Dubbo, y el objeto proxy de interfaz de servicio correspondiente se generará automáticamente y se registrará en el registro de Dubbo para que llamen otros consumidores de servicios. El uso de esta anotación puede simplificar los pasos de publicación y exposición de los servicios de Dubbo y mejorar la eficiencia del desarrollo.
Luego cree una clase de inicio SpringBoot ProviderApplication
con el siguiente contenido
@SpringBootApplication
@EnableDubbo
public class ProviderApplication {
public static void main(String[] args) {
SpringApplication.run(ProviderApplication.class, args);
}
}
Se ha añadido una anotación @EnableDubbo
, después de intentarlo no hay problema sin esta anotación (pero es mejor añadirla para evitar otros problemas)
Modifique el archivo de configuración de SpringBoot, porque el proyecto Maven que creé, entonces necesita crear una nueva aplicación.propiedades o aplicación.yml en src/main/resources
propiedades
dubbo.application.name=demo-provider
dubbo.protocol.name=dubbo
dubbo.protocol.port=-1
dubbo.registry.address=zookeeper://${zookeeper.address:127.0.0.1}:2181
yml
dubbo:
application:
name: dubbo-springboot-demo-provider
protocol:
name: dubbo
port: -1
registry:
address: zookeeper://${
zookeeper.address:127.0.0.1}:2181
De esta manera, el proveedor de servicios hace un buen trabajo
consumidor de servicios (consumidor de demostración)
demo-consumer es un módulo de consumidor, cree un nuevo paquete demo.consumer y cree una clase de inicio ConsumerApplication en el paquete, el contenido es el siguiente
package demo.consumer;
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@EnableDubbo
public class ConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class, args);
}
}
Aquí debe escribir una interfaz web, por lo que debe agregar dependencias web en pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
Cree una nueva clase llamada TestControl con los siguientes contenidos
package demo.consumer;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import demo.Service;
@RestController
public class TestControl {
@DubboReference
private Service service;
@GetMapping("/")
public String test(String name) {
return service.sayHi(name);
}
}
Una interfaz web se define arriba, la ruta es /
, la interfaz recibe un nombre de parámetro, la interfaz llamará a la función sayHi de la cantidad del servicio y se pasa el parámetro de nombre.
El servicio aquí usa @DubboReference
la inyección de anotaciones, y llamar a sayHi es en realidad equivalente a llamar a sayHi de la clase de implementación del proveedor de demostración.
No quiero entender el principio aquí, solo adivine un poco, según mi forma de pensar, debería ser aproximadamente que el proveedor y el consumidor se conectan a zookeeper, el consumidor se comunica con el proveedor a través de zookeeper y el consumidor usa el objeto inyectado por @DubboReference. Supongo que RPC envía datos al proveedor. Por ejemplo, la clase es Servicio y la función es decir Hola, luego enviar un Servicio | decir Hola. Después de recibir los datos, el proveedor encontrará la clase de implementación correspondiente, y implementar la función de la clase de implementación y luego ejecutar los datos devueltos, el resto son los detalles, como parámetros y similares. Por supuesto, solo estoy usando mis ideas para implementar dicho marco aquí y proporcionar una idea simple. Para conocer los detalles, aún necesita mirar el código fuente, la documentación y la depuración.
El archivo de configuración de SpringBoot es el mismo que el del proveedor, pero se requiere server.port para configurar el puerto web
De esta forma, el consumidor también ha hecho un buen trabajo
Obtenga servicio no a través de anotaciones, sino a través de contexto
Vamos a extenderlo aquí. A veces, las anotaciones no se pueden usar para inyectar objetos. En este momento, necesita obtener objetos de proveedor de otras maneras.
Obtenga el código de la siguiente manera
ReferenceConfig<Service> referenceConfig = new ReferenceConfig<>();
referenceConfig.setInterface(Service.class);
Service service = referenceConfig.get();
iniciar aplicación
corre ProviderApplication
yConsumerApplication
Cabe señalar que el proveedor debe iniciarse antes de iniciar el consumidor; de lo contrario, el módulo del consumidor informará un error y hará que todo el programa finalice. Este problema se @DubboReference
debe a las anotaciones. De forma predeterminada, comprobará si el proveedor correspondiente está disponible al inicio. Por supuesto, la comprobación se puede cancelar a través de la configuración o similar.
Hay varias soluciones
-
Agregue el parámetro check = false a la anotación, por ejemplo
@DubboReference(check = false)
-
Agregar contenido al archivo de configuración de SpringBoot
-
aumentan las propiedades
dubbo.consumer.check=false
-
aumento de yml
-
dubbo: consumer: check: false
-
-
Agregue el siguiente código en la clase de inicio o clase de configuración
-
@Bean public ConsumerConfig consumerConfig() { ConsumerConfig consumerConfig = new ConsumerConfig(); consumerConfig.setCheck(false); return consumerConfig; }
-
Después de iniciar, el servicio al consumidor explotará algunos errores, pero no afecta, acceda a la dirección a través del navegador, el efecto es el siguiente
problema resuelto
[DUBBO] qos-server can not bind localhost:22222, dubbo version: 3.2.0-beta.4, current host: 192.168.0.108, error code: 7-4. This may be caused by , go to https://dubbo.apache.org/faq/7/4 to find instructions.
java.net.BindException: Address already in use: bind
...
Fail to start qos server: , dubbo version: 3.2.0-beta.4, current host: 192.168.0.108, error code: 7-4. This may be caused by , go to https://dubbo.apache.org/faq/7/4 to find instructions.
java.net.BindException: Address already in use: bind
Este error significa que el puerto del servicio qos está ocupado, porque el servidor qos se iniciará automáticamente cuando se inicie con Dubbo. El puerto predeterminado es 22222. Inicié el proveedor y el consumidor en la misma computadora anterior, por lo que informé este error.
El servidor QoS (Calidad de servicio) de Dubbo es un servidor independiente que se utiliza para garantizar la calidad del servicio de Dubbo y monitorear y administrar los indicadores relacionados con el servicio.
Se puede solucionar modificando el archivo de configuración de SpringBoot
propiedades
# 是否启用,默认启用
dubbo.application.qosEnable=true
# 端口,默认22222
dubbo.application.qosPort=12345
dubbo.application.qosAcceptForeignIp=false
Hasta ahora, el uso básico ha estado bien.
FIN