Desta vez, compartilho com você como consumir serviços. O artigo anterior fala sobre o uso do Feign para consumo, este artigo usa serviços de consumo de REST+Ribbon e personaliza um componente de consumo simples por meio da pesquisa. O objetivo deste artigo é: a idéia de personalizar serviços de consumo; Se houver alguma vantagem, por favor "como":
REST+Ribbon realiza serviços de consumidor
Como consumidor de serviço, fizemos dois processos principais para distinguir entre 1) obtenção de serviços e 2) serviços de chamada. Então, como obter serviços e o que chamar de serviços? Vamos dar uma olhada em um diagrama manual abaixo:
Pode ser visto no diagrama manual que o consumidor primeiro obtém o endereço de interface real do provedor de serviços e depois chama a interface através do endereço; Então, para a arquitetura de microsserviços, definitivamente não é aconselhável obter um determinado IP ou porta de classe e depois chamar a interface; portanto, surgiu um conceito de serviço no microsserviço; O processo simples foi introduzido, e a seguir é um exemplo para analisá -lo; Primeiro, adicione dependências como:
<Depencency> <PuerpId> org.springframework.boot </frugiD> <ArtifactId> Spring-boot-starter-web </artifactId> </dependency> <pendesency> </Groupid> org.springframework.cloud </groupid> <Artifactid> Spring-starter-eure
Vamos usar o eureka_server (centro de serviço) e eureka_provider (provedor de serviços) construídos no artigo anterior para realizar casos de teste. Aqui eu redefino o módulo eureka_consumer_ribbon como um serviço de consumidor; Primeiro, crie a classe e o código da camada de serviço:
@ServicePublic Class UserService implementa o UserInterface {@AUTOWIRED RESTTEMPLAT protegido 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); retornar str; }}Use principalmente a função RestTemplate.GetForObject do RestTemplate e, em seguida, você precisa definir um controlador para responder aos dados obtidos na página. Para simplificar, basta usar a interface de serviço getMSG para testar:
@RestControllerPublic Classe UserController {@AUTOWIRED PRIVADO UserService UserService; @GetMapping ("/msg") public string getMsg () {return userservice.getmsg (); }}Por fim, adicionamos o seguinte código à classe de inicialização. Observe que a tag @loadBalanced deve ser adicionada, porque a dependência Eureka que introduzimos contém fita (versão Dalston.release). A fita encapsula o algoritmo de balanceamento de carga. Se essa anotação não for adicionada, o URL do método restante deve ser o caminho da URL disponível. Obviamente, se a anotação for adicionada aqui, você poderá usar o serviço mencionado acima:
@SpringboOTApplication @Enablediscoveryclient // CLASS Public Client Public EurekaconsumerRribbonApplication {@Bean @loadBalanced // Carregar balanceamento resttemplate RestTemplate () {return new Resttemplate (); } public static void main (string [] args) {springapplication.run (eurekaconsumerribbonapplication.class, args); }}A seguir, é apresentado o efeito exibido pelo consumidor:
REST+POLL Componentes de consumo simples personalizados
O componente de consumo personalizado é quase o mesmo que o desenho manual do rosto. É primeiro obter o endereço de interface real do provedor de serviços e depois ligar para o URL através do REST para obter a saída de resultado correspondente; Aqui está uma classe de componentes Shenniubanlance:
/** * Criado por Shenniu em 2018/6 * <P> * REST+EUREKA+CLIENTE CUDDADO */ @ComponentPublic Classe ShenniubanLance {@aUTowired Private Resttemplate Resttemplate; @Autowired Private Discoveryclient Discoveryclient; / ** * Endereço real do serviço ConcurrentHashMap <"Nome do aplicativo de serviço", ("IP da interface real", número de visitas)> */ public static concurrenthashmap <string, list <Moservice>> ServiceMap = new ConcurrentHashMap <> (); /** * Defina as informações do provedor de serviços para mapear */public void SetServicesMap () {// Obtenha todo o provedor de serviços ApplicationName List <String> AppNames = Discoveryclient.getServices (); // armazenamento o endereço real a ser mapeado para (string appName: appNames) {// Obtenha informações de uma lista de provedores de serviços <VowInstance> instanceInfos = Discoveryclient.getInstances (AppName); if (instanceInfos.isEmpty ()) {continua; } Lista <Moservice> Serviços = new ArrayList <> (); instanceInfos.ForEach (b -> {Moservice Service = new Moservice (); // Número de Service.setWatch Accessado (0L); // Endereço de interface real Service.Seturl (B.Geturi (). ToString ()); Services.add (Service);}); // Se houver, atualizar ServiceMap.put (AppName.TolowerCase (), Services); }} / ** * Serviço selecionado de acordo com o app * * @param AppName * @return * / public Moservice ChoiceServiceByAppName (String appName) lança exceção {AppName = AppName.tolowerCase (); // Alguma lista de coleta de serviços de serviço de aplicativo <Moservice> servicemap = ServiceMap.get (AppName); if (servicemap == null) {// inicialize todos os serviços de aplicativos setServicesMap (); Servicemap = ServiceMap.get (AppName); if (servicemap == null) {lança nova exceção ("Falha ao encontrar" + appName + "Serviços Relacionados"); }} // filtre o método de pesquisa de serviço com o menor número de visitas a Moservice Moservice = servicemap.stream (). // Carregar registro +1 Moservice.setWatch (Moservice.getWatch () + 1); retornar Moservice; } / ** * Atualize automaticamente as informações do provedor de serviços para mapear * / @scheduled (fixedDelay = 1000 * 10) public void refreshServicesMap () {SetServicesMap (); } / ** * Obtenha o serviço de solicitação para obter os dados de retorno * * @param appName Nome do aplicativo ApplicationName * @param serviceName serviceName * @param mapa Parâmetro de solicitação de mapa no url * @param tclass return type * @param <t> * @return * / public <tty ttheServicedATATA (string AppName, string <t> tente {// filter para obter o serviço de serviço real de serviço = ChoiceServiceByAppName (AppName); // solicita o URL da string de serviço apiurl = service.geturl () + "/" + serviceName; System.out.println (apiurl); resultado = mapa! = nulo? RestTemplate.getForObject (apiurl, tclass, mapa): RestTemplate.getForObject (apiurl, tclass); } catch (Exceção ex) {ex.PrintStackTrace (); } resultado de retorno; } / *** Informações de serviço* / classe pública Moservice { / *** Número de registros de carga* / Private Long Watch; /** * Endereço real da interface: 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 (String url) {this.url = url; }}}O acima é o principal código de implementação. Lógica de código: defina as informações do provedor de serviços para mapear de acordo com o aplicativo para obter o método de votação, o serviço-》 solicita o serviço para obter os dados de retorno; O princípio da implementação da pesquisa é usar um número de registro de carga, que automaticamente +1 após cada solicitação. Quando você deseja obter um determinado provedor de serviços, uma instância do valor mínimo é filtrada através do número de registro e o URL do endereço da interface real é armazenado; A chamada só precisa ser assim (é claro, pode ser chamada de anotações):
@Override public String getmsg () {String str = Banlance.getServicededata ("Eureka-provider", "msg", null, string.class); retornar str; }Deve-se notar aqui que adicionamos a anotação @loadBalanced no RestTemplate anterior, para que a solicitação de restante deve ser acessada em um não-IP (ou seja, serviceId) para responder normalmente; caso contrário, um erro será solicitado como:
Simplificando, você não precisa mais usar IP porque existe um mecanismo de balanceamento de carga; Quando removemos essa anotação, nossos componentes personalizados poderão funcionar com sucesso, e as renderizações são as mesmas do Exemplo 1, e o mapa não será colocado;
Atualizar informações do provedor de serviços usando agendado
Na arquitetura do microsserviço, se um serviço estiver pendurado, as informações do cache de serviço do cliente devem ser atualizadas a tempo, caso contrário, poderá solicitar ao URL descendente. Com base nessa consideração, usei a tag Atablesched para executar a atualização cronometrada; Primeiro, adicione @enablescheduling à aula de inicialização e depois defina um serviço que exibe as informações de serviço como:
/ ** * Atualize automaticamente as informações do provedor de serviços para mapear */ @scheduled (fixoDELAY = 1000 * 10) public void refreshServicesMap () {SetServicesMap (); }Para facilitar o efeito do teste, quando o servidor, o provedor (2) e o consumidor foram iniciados, iniciamos um serviço de provedor com a porta 2005; Em seguida, atualize a interface do consumidor para ver o efeito:
Neste momento, você pode ver que a interface chamando a porta de 2005 foi chamada com sucesso. Depois que o serviço mais recente ou inválido é adicionado ao serviço cronometrado @Scheduled, ele atenderá às necessidades do que você precisa; Se você acha que esse conteúdo é útil para você, goste, obrigado. Espero que seja útil para o aprendizado de todos, e espero que todos apoiem mais o wulin.com.