Spring Cloud - Service Consumption

foreword

      The title originally wanted to write about service consumers, but I was afraid to put too much emphasis on the word "consumer", because in Eureka, service consumers can also be used as service producers to provide services, so only service consumption is written here. There are two ways to consume services in Eureka, one is the rest+ribbon way, and the other is the Feign way.

Rest+Ribbon

      As mentioned in the previous blog, create a Spring Boot project and add a reference to Ribbon; if it is Spring Boot 1.0, add a reference to Ribbon as:

<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-ribbon</artifactId>
</dependency>

If you are using Spring Boot 2.0 and the id of the Ribbon reference is different, add the Ribbon reference as:

<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>

Add configuration in application.properties file:

server.port=8765
eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/
spring.application.name=consumer-ribbon

Add the annotation @EnableEurekaClient to the startup class to achieve registration with Eureka Server, and inject RestTemplate in the form of beans, as shown below:

@SpringBootApplication
@EnableDiscoveryClient
@RestController
public class ConsumerRibbonApplication {

	public static void main(String[] args) {
		SpringApplication.run(ConsumerRibbonApplication.class, args);
	}

	@Bean
	@LoadBalanced
	RestTemplate restTemplate(){
		return new RestTemplate();
	}

	@Autowired
	private HelloService helloService;

	@GetMapping(value = "/ribbon/sayHello")
	public String hello(String name){
		return helloService.hiService(name);
	}
}

      The Controller layer is not created here, the startup class is directly annotated as Controller, and the specific business logic is placed in the implementation of the Service. What Service does is to call the producer's service according to the service address to be called:

@Service
public class HelloServiceImpl implements HelloService{

    @Autowired
    RestTemplate restTemplate;

    @Override
    public String hiService(String name) {
        return restTemplate.getForObject("http://EUREKA-PRODUCER-HELLO/hello?name="+name,String.class);
    }
}

      As shown in the above code, Eureka only needs to use the service name when calling the producer service, and Ribbon will perform load balancing based on the machine that registers the service name. There are two machines with the name EUREKA-PRODUCER-HELLO registered by me, which are distinguished by port, and the port number of the machine is printed when calling. When starting the consumer-ribbon, you can see the change of the output port number after accessing it multiple times, which means that multiple service producers provide services.

Ribbon is a client-side payload that has by default implemented the configuration bean shown below:

Bean Type Bean Name Class Name

IClientConfig

ribbonClientConfig

DefaultClientConfigImpl

IRule

ribbonRule

ZoneAvoidanceRule

IPing

ribbonPing

DummyPing

ServerList<Server>

ribbonServerList

ConfigurationBasedServerList

ServerListFilter<Server>

ribbonServerListFilter

ZonePreferenceServerListFilter

ILoadBalancer

ribbonLoadBalancer

ZoneAwareLoadBalancer

ServerListUpdater

ribbonServerListUpdater

PollingServerListUpdater

Feign

      Using this method to call, also create a Spring Boot project as described in the previous blog, and then add Feign dependencies. Similarly, Spring Boot 1.0 and Spring Boot 2.0 have different reference methods. The following is a reference to 2.0:

<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

      Similarly, add the annotation @EnableEurekaClient to the startup class to register with Eureka Server, and add the annotation @EnableFeignClients to call the service producer using Feign, as shown below:

@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
@RestController
public class ConsumerFeignApplication {

	public static void main(String[] args) {
		SpringApplication.run(ConsumerFeignApplication.class, args);
	}

	@Autowired
	private HelloServiceFeignClient helloServiceFeignClient;


	@GetMapping(value = "/feign/sayHello")
	public String sayHello(@RequestParam("name") String name){
		return helloServiceFeignClient.sayHello(name);
	}
}

HelloServiceFeignClient in the above code is an interface used to call other services, in a style similar to Restful:

@FeignClient(value = "EUREKA-PRODUCER-HELLO")
@Component
public interface HelloServiceFeignClient {

    /**
     * say hello
     * @param name
     * @return
     */
    @GetMapping(value = "/hello")
    String sayHello(@RequestParam("name") String name);
}

      The value in the @FeignClient annotation represents the name of the service to be accessed. The url in the following method represents the url to access the service. The @GetMapping annotation can also be replaced by the @RequestMapping(method = RequestMethod.GET) annotation, and the post call method is the same. For parameters, the value in @RequestParam should correspond to the parameter name of the server. If multiple parameters are passed in, you can use @RequestBody to annotate the entity to achieve this.

      FeignClient inherits Ribbon by default, so the load balancing of this calling method is also implemented by Ribbon. In addition, if you want to call multiple services in one service, you need to create multiple interface classes, just change the value of @FeignClient to the corresponding service name, so that you can call methods in different services by injecting different interfaces.

afterword

      Personally, I think the FeignClient method is easy to use. I am used to the Restful calling method. I feel that the FeignClient method is very pleasing to the eye and very convenient, and the code style during cooperative development is relatively uniform. It would be better if the service provider provided a jar package. You don't even need to write the interface. You can directly use the other party's jar package to call the Eureka service, and you can also use the other party's returned entity. There are too few places to do it yourself. But in this case, your own service still needs to be registered on EurekaServer, because after all, it is still called by FeignClient.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324745334&siteId=291194637