Esta vez comparto con usted cómo consumir servicios. El artículo anterior habla sobre el uso de Feign para el consumo, este artículo utiliza servicios de consumo de cinta REST+y personaliza un componente de consumo simple a través de las encuestas. El propósito de este artículo es: la idea de personalizar los servicios de consumo; Si hay alguna ventaja, por favor "me gusta":
REST+Ribbon realiza los servicios de consumo
Como consumidor de servicios, hemos realizado dos procesos principales para distinguir entre 1) obtener servicios y 2) servicios de llamadas. Entonces, ¿cómo obtener servicios y qué llamar a los servicios? Echemos un vistazo a un diagrama manual a continuación:
Se puede ver en el diagrama manual que el consumidor obtiene primero la dirección de interfaz real del proveedor de servicios, y luego llama a la interfaz a través de la dirección; Luego, para la arquitectura de microservicio, definitivamente no es aconsejable obtener una determinada IP o puerto de clase y luego llamar a la interfaz, por lo que ha surgido un concepto de servicio en el microservicio; Se ha introducido el proceso simple, y el siguiente es un ejemplo para analizarlo; Primero agregue dependencias como:
<Spendency> <MoupRoMID> org.springframework.boot </groupid> <artifactID> spring-boot-starter-web </artifactid> </pendency> <pendency> <grupoD> org.springframework.cloud </groupId> <artifactid> spring-nube-starter-eureka </artifactid> </dependency>
Usemos el Eureka_Server (Centro de servicio) y Eureka_Provider (proveedor de servicios) construido en el artículo anterior para realizar casos de prueba. Aquí redefine el módulo Eureka_consumer_ribbon como un servicio de consumo; Primero cree la clase de capa de servicio y el código:
@ServicePublic Class UserService implementa UserInterface {@aUtowired RestTemplate RestTemplate; @Override public MORP <list <mouser>> getUsers (Morq rq) {return null; } @Override public String getMsg () {String str = RestTemplate.getForObject ("http: // eureka-provider/msg", string.class); regresar str; }}Utilice principalmente la función RESTTemplate.getForObject de RestTemplate, y luego debe definir un controlador para responder a los datos obtenidos en la página. Para simplificar, solo use la interfaz de servicio GetMSG para probar:
@RestControllerPublic Class UserController {@aUtowired private UserService UserService; @GetMapping ("/msg") public String getMsg () {return userservice.getMsg (); }}Finalmente, agregamos el siguiente código a la clase de inicio. Tenga en cuenta que se debe agregar la etiqueta @LoadBalanced , porque la dependencia de Eureka que presentamos contiene cinta (versión dalston.release). La cinta encapsula el algoritmo de equilibrio de carga. Si no se agrega esta anotación, la URL del método REST debe ser la ruta de URL disponible. Por supuesto, si la anotación se agrega aquí, puede usar el servicio de servicio mencionado anteriormente:
@Springbootapplication @habilitedScoveryClient // Consumer Client Public Class EurekaconsumerribbonApplication {@Bean @LoadBalanced // Load Balancing RestTemplate RestTemplate () {return New RestTeMplate (); } public static void main (string [] args) {springapplication.run (eurekaconsumerribbonapplication.class, args); }}El siguiente es el efecto que muestra el consumidor:
REST+POLLA COMPONENTES DE CONSUMO SIMPLES Custom
El componente de consumo personalizado es casi el mismo que el dibujo manual de la cara. Primero es obtener la dirección de interfaz real del proveedor de servicios, y luego llamar a la URL a través de REST para obtener la salida de resultados correspondiente; Aquí hay una clase de componentes Shenniubanlance:
/** * Creado por Shenniu en 2018/6 * <p> * REST+EUREKA+CLIENTE Custom */ @ComponentPublic ShenniUbanlance {@AUTOWired RestTemplate RestTemplate; @Autowired Private DiscoveryClient DiscoveryClient; / ** * Servicio Dirección real ConcurrenthashMap <"Nombre de la aplicación de servicio", ("IP de interfaz real", número de visitas)> */ public static concurrenthashmap <string, list <service>> ServicesMap = new concurrentHashMap <> (); /** * Establezca información del proveedor de servicios para mapear */public void setServicesMap () {// Obtener todos los servicios del proveedor de servicios Lista de nombre <string> appnames = DiscoveryClient.getServices (); // Almacenamiento de la dirección real para mapear (String AppName: AppNames) {// Obtener información de una lista de proveedores de servicios <ServiceInstance> instanceInfos = DiscoveryClient.getInstances (AppName); if (instanceInfos.isEmpty ()) {continuar; } List <moservice> Services = new ArrayList <> (); instanceInfos.ForEach (B -> {Moservice Service = new Moservice (); // Número de servicio de acceso. // Si existe, actualizar ServicesMap.put (appname.tolowercase (), servicios); }} / ** * Servicio seleccionado de acuerdo con la aplicación * * @param AppName * @return * / public MoserviceServiceByAppname (String AppName) lanza la excepción {appname = appname.tolowerCase (); // Lista de colección de servicios de servicio de aplicaciones <Service> ServiceMap = ServicesMap.get (AppName); if (serviceMap == null) {// Inicializar todos los servicios de aplicaciones setServicesMap (); ServiceMap = ServicesMap.get (AppName); if (serviceMap == null) {tirar nueva excepción ("Error al encontrar" + AppName + "Servicios relacionados"); }} // Filtrar el método de votación del servicio con el menor número de visitas Moservice Moservice = ServiceMap.stream (). Min (comparador.comparing (moservicio :: getwatch)) .get (); // Cargar registro +1 moservice.setWatch (moservice.getwatch () + 1); Moservicio de regreso; } / ** * Actualice automáticamente la información del proveedor de servicios para mapear * / @scheduled (fixeddelay = 1000 * 10) public void RefreshServicesMap () {setServicesMap (); } /** * get request service to get the return data* * @param appName Application name ApplicationName * @param serviceName ServiceName * @param map request parameter on url* @param tClass Return type* @param <T> * @return */ public <T> T getServiceData( String appName, String serviceName, Map<String, ?> map, Class<T> tClass) { T result = null; Pruebe {// Filtro para obtener el servicio real Moservice Service = ChoiceserviceByAppName (AppName); // Solicite la URL de la cadena de servicio apiURL = servicio.getUrl () + "/" + ServiceName; System.out.println (apiurl); resultado = map! = nulo? RestTemplate.getForObject (apiurl, tcLass, map): resttemplate.getforObject (apiurl, tclass); } catch (Exception Ex) {Ex.PrintStackTrace (); } resultado de retorno; } / *** Información de servicio* / Moservicio de clase pública { / *** Número de registros de carga* / Reloj largo privado; /** * Dirección de la interfaz real: http://xxx.com/api/add */private string url; public Long GetWatch () {Return Watch; } public void setWatch (Long Watch) {this.watch = watch; } public String getUrl () {return url; } public void seturl (url de cadena) {this.url = url; }}}Lo anterior es el código de implementación principal. Lógica del código: configure la información del proveedor de servicios en MAP-》 Según la aplicación para obtener el método de votación, el servicio》 solicita el servicio para obtener los datos de retorno; El principio de la implementación de la encuesta es usar un número de registro de carga, que automáticamente +1 después de cada solicitud. Cuando desea obtener un determinado proveedor de servicios, se filtra una instancia del valor mínimo a través del número de registro, y la URL de la dirección de la interfaz real se almacena; La llamada solo debe ser así (por supuesto, se puede llamar como anotaciones):
@Override public String getMsg () {string str = banlance.getServiceData ("Eureka-Provider", "msg", null, string.class); regresar str; }Cabe señalar aquí que agregamos la anotación @LoadBalanced en el RESTTemplate anterior, de modo que se debe acceder a la solicitud de reposo en un no IP (es decir, ServiceId) para responder normalmente, de lo contrario, se solicitará un error, como:
En pocas palabras, ya no necesita usar IP porque hay un mecanismo de equilibrio de carga; Cuando eliminemos esta anotación, nuestros componentes personalizados podrán ejecutarse con éxito, y las representaciones son las mismas que las del Ejemplo 1, y el mapa no se adhirirá a;
Actualizar información del proveedor de servicios utilizando programado
En la arquitectura de microservicio, si se cuelga un servicio, la información de caché del servicio del cliente debe actualizarse a tiempo, de lo contrario puede solicitar la URL de baja. Basado en esta consideración, utilicé la etiqueta Actualización para realizar la actualización cronometrada; Primero agregue @EnablesCheduling a la clase de inicio y luego defina un servicio que parpadee la información del servicio, como:
/ ** * Actualiza automáticamente la información del proveedor de servicios para mapear */ @scheduled (fixeddelay = 1000 * 10) public void refreshServicesMap () {setServicesMap (); }Para facilitar el efecto de prueba, cuando se ha iniciado el servidor, el proveedor (2) y el consumidor, iniciamos un servicio de proveedor con Port 2005; Luego, actualice la interfaz del consumidor para ver el efecto:
En este momento, puede ver que la interfaz que llama al puerto 2005 se ha llamado con éxito. Después de agregar el último servicio o inválido al servicio cronometrado @Scheduled, satisfará las necesidades de lo que necesita; Si cree que este contenido es útil para usted, por favor me guste, gracias. Espero que sea útil para el aprendizaje de todos, y espero que todos apoyen más a Wulin.com.