Spring cloud: service provision and Feign call

In this article, there are three roles: service provider, service consumer, and the protagonist of the previous article, the registration center Eureka (just use the stand-alone version, and the example in this article will also use the stand-alone version of Eureka).

The overall process is as follows:
Start the registration center Eureka first
The provider that starts the service will provide the service and register the service with Eureka, the registry
The consumer who starts the service finds the service in the registration center and completes the consumption (understand the source code and ask: 1791743380)
1. Service provider

1. pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.springcloud</groupId>
    <artifactId>producer</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>producer</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Greenwich.SR1</spring-cloud.version>
    </properties>

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

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

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

2. Configuration file application.yml

server:
  port: 8080
spring:
  application:
    name: spring-cloud-producer
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/

3. Startup class ProducerApplication.java
Add @ EnableEurekaClient. Other registries can use the annotation @ EnableDiscoveryClient to register services

package com.springcloud.producer;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

@SpringBootApplication
@EnableEurekaClient
public class ProducerApplication {

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

}

4. Controller

package com.springcloud.producer.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

/**
 * Created with IntelliJ IDEA.
 *
 * @Date: 2019/7/2
 * @Time: 0:02
 * @email: inwsy@hotmail.com
 * Description:
 */
@RestController
public class HelloController {
    @RequestMapping("/hello")
    public String hello(@RequestParam String name) {
        return "hello "+name+",producer is ready";
    }
}

First, you can start the Eureka of the stand-alone version in the previous article, and then start the producer service provider that we just wrote. After the startup is successful, visit the link http://localhost:8761 /, you can see that our service provider producer has successfully registered in the registry.

At this point, the provider of the service has been configured.

2. Service consumers

1. pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.springcloud</groupId>
    <artifactId>consumers</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>consumers</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Greenwich.SR1</spring-cloud.version>
    </properties>

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

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

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

Spring boot starter Web: this package is a general web development package, which includes spring web, spring webmvc and other packages

Spring Cloud starter openfeign: this package is the encapsulation of feign by Spring Cloud. Feign is a declarative Web service client. It supports feign's own annotations, JAX-RS annotations, and spring MVC annotations. Spring Cloud integrates Ribbon and Eureka to provide a load balanced http client when using feign.

2. Configuration file application.yml

server:
  port: 8081
spring:
  application:
    name: spring-cloud-consumers
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/

3. Startup class ConsumersApplication.java
As above, add @ EnableEurekaClient. Other registries can use the annotation @ EnableDiscoveryClient to register services

package com.springcloud.consumers;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.openfeign.EnableFeignClients;

@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class ConsumersApplication {

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

}

@Enable feignclients: this annotation tells spring boot to scan the classes decorated by @ FeignClient when it is started. The @ FeignClient annotation will be used when making remote calls.

4. Feign remote call
Feign is a declarative Web Service client. Using feign can make it easier to write a Web Service client. Its use method is to define an interface, and then add comments on it. At the same time, it also supports JAX-RS standard comments. Feign also supports pluggable encoders and decoders. Spring Cloud encapsulates feign to support Spring MVC standard annotations and HttpMessageConverters. Feign can be combined with Eureka and Ribbon to support load balancing.

Create a remote interface

package com.springcloud.consumers.remote;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

/**
 * @Author: shiyao.wei
 * @Date: 2019/7/2 11:14
 * @Version: 1.0
 * @Desc:
 */
@FeignClient(name= "spring-cloud-producer")
public interface HelloRemote {
    @RequestMapping(value = "/hello")
    String hello(@RequestParam(value = "name") String name);
}

Name: remote service name, and spring.application.name Name of the configuration
The method names and parameters in this class should be consistent with those in the container in the remote service
5. The web layer calls the remote interface Controller

package com.springcloud.consumers.controller;

```java
import com.springcloud.consumers.remote.HelloRemote;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @Author: shiyao.wei
 * @Date: 2019/7/2 11:25
 * @Version: 1.0
 * @Desc:
 */
@RestController
public class HelloController {
    @Autowired
    HelloRemote helloRemote;

    @RequestMapping("/hello/{name}")
    public String index(@PathVariable("name") String name) {
        return helloRemote.hello(name);
    }
}
Now, a simple example of service registration and invocation is completed.

**3. Test**
Simple call
 Launch three projects successively: eureka, producer and consumer

After the startup is successful, enter the http://localhost:8080/hello?name=springcloud

You can see the page display: hello springcloud, producer is ready

It proves that our producer has started normally and the services provided are normal

Next, we test the service consumer and enter: http://localhost:8081/hello/spring

You can see the page display: hello spring, producer is ready

It indicates that the client has successfully called the remote service hello through feign and returned the result to the browser.

load balancing 
Make a copy of the above producer, change the name to producer 2, and modify pom.xml \ \ in is producer2, modify the Controller:
```java
package com.springcloud.producer.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

/**
 * Created with IntelliJ IDEA.
 *
 * @Date: 2019/7/2
 * @Time: 0:02
 * @email: inwsy@hotmail.com
 * Description:
 */
@RestController
public class HelloController {
    @RequestMapping("/hello")
    public String hello(@RequestParam String name) {
        return "hello "+name+",producer2 is ready";
    }
}

modify application.yml Profile start port is 8082

Start the producer 2 that we just copied. Now you can take a look at the registration center Eureka. Now we have two producer services.

Then we will visit: http://localhost:8081/hello/spring

The first returned result: hello spring, producer is ready

The second return result: hello spring, producer 2 is ready

Refresh the page continuously, and the two results will appear alternately, indicating that the registry provides the service load balancing function. When the number of services is increased to N, it will be found that the test results are the same, and the request will be automatically polled to each server for processing.

Tags: Spring Maven Java Apache

Posted on Tue, 09 Jun 2020 23:28:52 -0400 by jabapyth