Spring cloud tutorial 2: Two ways to create service consumers

Spring cloud tutorial 2: Two ways to create service consumers

1,Ribbon + RestTemplate

1.1 Preparations:

Create a registry with port 8761: How to create it

pom.xml needs to introduce dependencies: eureka-server

main program add annotation @EnableEurekaServer

​ application.properties:

eureka.client.service-uri.default-zone =  http://localhost:8761/eureka/
eureka.client.Also registry-with-eureka and fetch....
server.port = 8761

This will set up your registration center.

Next, create a service provider:

pom.xml needs to be introduced: eureka-client

main program:

@SpringBootApplication
@EnableEurekaClient
@RestController
public class ServiceHiApplication {

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

	@Value("${server.port}")
	String port;
	@RequestMapping("/hi")
	public String home(@RequestParam String name) {
		return "hi "+name+",i am from port:" +port;
	}

}

It is not enough to just @Enable EurekaClient. You also need to specify the address of your service registry in the configuration file. The application.yml configuration file is as follows:

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/
server:
  port: 8762
spring:
  application:
    name: service-hi				

Opening Eureka-server and service provider in turn, we find that a service has been registered in the service, the service name is SERVICE-HI, and the port is 8762.

When you open http://localhost:8762/hi?name=yourname, you will see on the browser:

hi yourname,i am from port:8762

Note: Changing the port of the configuration file to run, you will find two other service providers with the same port, which is the high availability of micro services.

1.2 Create service consumers:

Rebuild a new spring-boot project named service-ribbon; in its pom.xml file, introduce the start dependencies of spring-cloud-starter-eureka, spring-cloud-starter-ribbon, spring-boot-starter-web, respectively. The code is as follows:

pom.xml

<dependencies>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-netflix-eureka</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-ribbon</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

application.yml:

#Registration service to registry
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/
      #port
server:
  port: 8764
  #Name of registration in the registry
spring:
  application:
    name: service-ribbon

In the project startup class, register with the service center through @Enable Discovery Client; inject a bean: restTemplate into the ioc of the program; and annotate @LoadBalanced to show that the restRemplate opens the load balancing function.

@SpringBootApplication
@EnableDiscoveryClient
public class ServiceRibbonApplication {

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

	@Bean
    //Open Load Balancing Ribbon
	@LoadBalanced
	RestTemplate restTemplate() {
		return new RestTemplate();
	}

}

Write a test class HelloService to consume the'/ Hi'interface of service-hi service by restTemplate injected into the ioc container. Here we use the program name directly instead of the specific url address. In ribbon, it will select the specific service instance according to the service name. According to the service instance, it will be used when requesting. The url of the body replaces the service name with the following code:

@Service
public class HelloService {

    @Autowired
    RestTemplate restTemplate;

    public String hiService(String name) {
        //Here, call getForObject of restTemplate to get the object returned by the interface http://SERVICE-HI/hi?name=
        //restTemplate also has many get methods, which you may be interested in studying, such as getForEntity(uri,Object)
        return restTemplate.getForObject("http://SERVICE-HI/hi?name="+name,String.class);
    }

}

Write a controller and call HelloService in the controller. The code is as follows:

@RestController
public class HelloControler {

    @Autowired
    HelloService helloService;
    @RequestMapping(value = "/hi")
    public String hi(@RequestParam String name){
        return helloService.hiService(name);
    }


}

Visit http://localhost:8764/hi?name=fd many times on browser, browser alternately shows:

hi fd,i am from port:8762

hi fd,i am from port:8763

This shows that when we call restTemplate.getForObject("http://SERVICE-HI/hi?name="+name,String.class) method, we have done load balancing and accessed service instances of different ports. (The @LoadBalance annotation above RestTemplate of main program)

At this time, the architecture of microservices is:

  • A service registry, eureka server, port 8761
  • The service-hi project runs two examples, with ports 8762 and 8763, registering with the service registry respectively.
  • sercvice-ribbon port 8764, registered with service registry
  • When sercvice-ribbon calls the hi interface of service-hi through restTemplate, the hi interface of service-hi: 8762 and 8763 ports will be invoked alternately because of load balancing with ribbon.

2,Feign

That's a little demo of Ribbon+RestTemplate for service consumers

So what is Feign?

2.1 Introduction to feign

Feign is a declarative pseudo-Http client that makes it easier to write Http clients. With Feign, you only need to create an interface and annotate it. It has pluggable annotation features and can use Feign annotations and JAX-RS annotations. Feign supports pluggable encoders and decoders. Feign integrates Ribbon by default and combines with Eureka to achieve load balancing by default.

In short:

  • Feign uses interface-based annotations
  • Feign integrates ribbon

2.2 Preparations

Continue to use the previous section of the project, start eureka-server, port 8761; start service-hi twice, port 8762, 8763, respectively.

2.3. Create a feign service

A new spring-boot project named service-feign is constructed. In its pom file, it introduces Feign's starting dependence on spring-cloud-starter-netflix-openfeign, Eureka's starting dependence on spring-cloud-starter-netflix-eureka, and Web's starting dependence on spring-boot-starter-web. The code is as follows:

<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-netflix-eureka</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-netflix-openfeign</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>

Spring cloud version with the latest

In the engineering configuration file application.yml file, the specified program is named service-feign, the port number is 8765, and the service registration address is http://localhost:8761/eureka/. The code is as follows:

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/
server:
  port: 8765
spring:
  application:
    name: service-feign

In the program startup class ServiceFeignApplication, add the @EnableFeignClients annotation to open Feign functions:

@SpringBootApplication
@EnableDiscoveryClient
//Open feign client
@EnableFeignClients
public class ServiceFeignApplication {

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

Define a feign interface to specify which service to invoke by @ FeignClient (value= "service name"). For example, the "/hi" interface of the service-hi service is invoked in the code. The code is as follows:

@FeignClient(value = "service-hi")
public interface SchedualServiceHi {
    @RequestMapping(value = "/hi",method = RequestMethod.GET)
    String sayHiFromClientOne(@RequestParam(value = "name") String name);
}

In the controller layer, an API interface of "/ hi" is exposed, and services are consumed through the Feign client SchedualService Hi defined above. The code is as follows:

@RestController
public class HiController {

    @Autowired
    SchedualServiceHi schedualServiceHi;
    @RequestMapping(value = "/hi",method = RequestMethod.GET)
    public String sayHi(@RequestParam String name){
        return schedualServiceHi.sayHiFromClientOne(name);
    }
}

Start the program, visit http://localhost:8765/hi?name=jd many times, browser alternately shows:

hi jd,i am from port:8762

hi jd,i am from port:8763

3. References

more details

For more details, please visit: juntech

Keywords: Spring xml

Added by neon on Tue, 10 Sep 2019 15:30:09 +0300