Welcome to my GitHub

Github.com/zq2599/blog…

Content: all original article classification summary and supporting source code, involving Java, Docker, Kubernetes, DevOPS, etc.;

“Java version of gRPC Combat” full series of links

  1. Generate code with Proto
  2. Service publishing and invocation
  3. The service side flow
  4. Client stream
  5. Two-way flow
  6. The client dynamically obtains the server address
  7. Registration discovery based on Eureka

About eureka

In the previous development of the client application, the required server address is set as follows:

  • Configure in application.yml as shown below:

  • In a bean that uses gRPC, the annotation GrpcClient can be used to inject the Stub class into a member variable:

  • The advantages of the above operation are that it is easy to configure, but the disadvantages are obvious: Once the IP address or port of the server is changed, you must modify application.yml and restart the client application.
  • You are smart enough to think of a solution: a registry! Eureka can be configured manually as long as the client can obtain the latest server address from the registry. The following is the general description of eureka:

This paper gives an overview of

  • If you have experience in Spring Cloud development, you should be familiar with restTemplate and Feign, etc., but the gRPC call in Spring Cloud environment is not so common. The goal of this article is to master the gRPC call in Spring Cloud environment. It is divided into the following chapters:
  1. Eureka application development
  2. GRPC server development
  3. GRPC client development
  4. validation
  5. A little bit confused

Download the source code

  • The full source code for this article can be downloaded at GitHub with the following address and link information (github.com/zq2599/blog…
The name of the link note
Project home page Github.com/zq2599/blog… The project’s home page on GitHub
Git repository address (HTTPS) Github.com/zq2599/blog… The project source warehouse address, HTTPS protocol
Git repository address (SSH) [email protected]:zq2599/blog_demos.git The project source warehouse address, SSH protocol
  • The git project has several folders. The source code for the gRPC Java Series is in the grPC-tutorials folder, as shown in the red box below:

  • The grPC-tutorials folder has multiple directories. The Eureka code for this article is in the Cloud-Eureka directory, the server code is in the Cloud-server-side directory, and the client code is in the Cloud-client-side directory, as shown below:

Eureka application development

  • Is credited with creating a module called cloud-eureka in parent project grpc-turtorials, whose build.gradle is described as follows:
// Use the Springboot plugin
plugins {
    id 'org.springframework.boot'
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter'
    / / rely on eureka
    implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-server'
    // State exposes required dependencies
    implementation 'org.springframework.boot:spring-boot-starter-actuator'
    // a project that relies on automatically generated source code
    implementation project(':grpc-lib')}Copy the code
  • Configuration file bootstrap. Yml, set its own web port and application name, the other had been. Client. ServiceUrl. DefaultZone configuration, please change your IP:
server:
  port: 8085

spring:
  application:
    name: cloud-eureka

eureka:
  instance:
    hostname: localhost
    prefer-ip-address: true
    status-page-url-path: /actuator/info
    health-check-url-path: /actuator/health
    lease-expiration-duration-in-seconds: 30
    lease-renewal-interval-in-seconds: 30
  client:
    registerWithEureka: false
    fetchRegistry: false
    serviceUrl:
            defaultZone: http://192.168.50.5:8085/eureka/
  server:
    enable-self-preservation: false

endpoints:
 shutdown:
  enabled: true
Copy the code
  • This module is only one class CloudEurekaApplication. Java:
package com.bolingcavalry.grpctutorials;

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

@EnableEurekaServer
@SpringBootApplication
public class CloudEurekaApplication {

    public static void main(String[] args) { SpringApplication.run(CloudEurekaApplication.class, args); }}Copy the code
  • This is a simple universal Eureka service;

GRPC server development

  • The gRPC server, which relies on Eureka, focuses on: first, configure to use Eureka, second, do not specify the port;

  • Torials are creating a module called cloud-server-side in the parent project grpc-turtorials, whose build.gradle is described as follows, and is credited with introducing GRPC server-related starter:

// Use the Springboot plugin
plugins {
    id 'org.springframework.boot'
}

dependencies {
    implementation 'org.projectlombok:lombok'
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.boot:spring-boot-starter'
    // As a gRPC service provider, you need this library
    implementation 'net.devh:grpc-server-spring-boot-starter'
    // As a client of Eureka
    implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
    // State exposes required dependencies
    implementation 'org.springframework.boot:spring-boot-starter-actuator'
    // a project that relies on automatically generated source code
    implementation project(':grpc-lib')
    // the annotationProcessor will not be passed, and modules that use lombok-generated code need to declare the annotationProcessor themselves
    annotationProcessor 'org.projectlombok:lombok'
}
Copy the code
  • Port and grpc.server.port are both set to 0, so both ports are automatically assigned unused values:
spring:
  application:
    name: cloud-server-side

server:
  port: 0
grpc:
  server:
    port: 0
eureka:
  instance:
    prefer-ip-address: true
    instanceId: ${spring.application.name}:${vcap.application.instance_id:${spring.application.instance_id:${random.value}}}
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://192.168.50.5:8085/eureka/
Copy the code
  • Start the class CloudServerSideApplication. Java:
package com.bolingcavalry.grpctutorials;

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

@EnableEurekaClient
@EnableDiscoveryClient
@SpringBootApplication
public class CloudServerSideApplication {

    public static void main(String[] args) { SpringApplication.run(CloudServerSideApplication.class, args); }}Copy the code
  • The GrpcServerService class that provides gRPC services is the same as in the local-server module:
package com.bolingcavalry.grpctutorials;

import com.bolingcavalry.grpctutorials.lib.HelloReply;
import com.bolingcavalry.grpctutorials.lib.SimpleGrpc;
import net.devh.boot.grpc.server.service.GrpcService;
import java.util.Date;

@GrpcService
public class GrpcServerService extends SimpleGrpc.SimpleImplBase {

    @Override
    public void sayHello(com.bolingcavalry.grpctutorials.lib.HelloRequest request, io.grpc.stub.StreamObserver
       
         responseObserver)
        {
        HelloReply reply = HelloReply.newBuilder().setMessage("1. Hello " + request.getName() + "," + newDate()).build(); responseObserver.onNext(reply); responseObserver.onCompleted(); }}Copy the code
  • The server code is the same as the local-server module except that gRPC port is set to 0 and eureka is normally used.

GRPC client development

  • For gRPC clients that rely on Eureka, the key points are as follows: First, use Eureka for configuration; second, the name of the gRPC configuration item in configuration should be equal to the name registered by the gRPC server in Eureka, as shown in the red box below:

  • Torials are creating a module called cloud-client-side in the parent project grpc-turtorials, whose build.gradle is described as follows, and is credited with introducing GRPC client-related starter:
// Use the Springboot plugin
plugins {
    id 'org.springframework.boot'
}

dependencies {
    implementation 'org.projectlombok:lombok'
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.boot:spring-boot-starter'
    // As a gRPC service user, you need this library
    implementation 'net.devh:grpc-client-spring-boot-starter'
    // As a client of Eureka
    implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
    // State exposes required dependencies
    implementation 'org.springframework.boot:spring-boot-starter-actuator'
    // a project that relies on automatically generated source code
    implementation project(':grpc-lib')
    // the annotationProcessor will not be passed, and modules that use lombok-generated code need to declare the annotationProcessor themselves
    annotationProcessor 'org.projectlombok:lombok'
}
Copy the code
  • The name of the gRPC cloud-server-side should be the same as the name of the gRPC server registered in Eureka, and the address configuration item is not required:
server:
  port: 8086
spring:
  application:
    name: cloud-client-side
eureka:
  instance:
    prefer-ip-address: true
    status-page-url-path: /actuator/info
    health-check-url-path: /actuator/health
    instanceId: ${spring.application.name}:${vcap.application.instance_id:${spring.application.instance_id:${random.value}}}
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://192.168.50.5:8085/eureka/
grpc:
  client:
    The name of the gRPC configuration used by the GrpcClient annotation
    cloud-server-side:
      enableKeepAlive: true
      keepAliveWithoutCalls: true
      negotiationType: plaintext
Copy the code
  • Start the class CloudClientSideApplication. Java, used the eureka related comments:
package com.bolingcavalry.grpctutorials;

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

@EnableEurekaClient
@EnableDiscoveryClient
@SpringBootApplication
public class CloudClientSideApplication {

    public static void main(String[] args) { SpringApplication.run(CloudClientSideApplication.class, args); }}Copy the code
  • GrpcServerService encapsulates the service class called by gRPC. As in the local-server module, GrpcClient annotation corresponds to the gRPC configuration item in the configuration:
package com.bolingcavalry.grpctutorials;

import com.bolingcavalry.grpctutorials.lib.HelloReply;
import com.bolingcavalry.grpctutorials.lib.HelloRequest;
import com.bolingcavalry.grpctutorials.lib.SimpleGrpc;
import io.grpc.StatusRuntimeException;
import net.devh.boot.grpc.client.inject.GrpcClient;
import org.springframework.stereotype.Service;

@Service
public class GrpcClientService {

    @GrpcClient("cloud-server-side")
    private SimpleGrpc.SimpleBlockingStub simpleStub;

    public String sendMessage(final String name) {
        try {
            final HelloReply response = this.simpleStub.sayHello(HelloRequest.newBuilder().setName(name).build());
            return response.getMessage();
        } catch (final StatusRuntimeException e) {
            return "FAILED with "+ e.getStatus().getCode().name(); }}}Copy the code
  • Make another Web interface class so that we can validate the gRPC service through a Web call:
package com.bolingcavalry.grpctutorials;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class GrpcClientController {

    @Autowired
    private GrpcClientService grpcClientService;

    @RequestMapping("/")
    public String printMessage(@RequestParam(defaultValue = "will") String name) {
        returngrpcClientService.sendMessage(name); }}Copy the code
  • After the client is developed, you can verify it.

validation

  • Start the cloud – eureka:

  • When cloud-server-side is started, we can see that the gRPC service port is automatically assigned 65141, but we don’t need to care about this value because the client can get it from Eureka:

  • Then cloud-client-side will be started, and the registration information of two services can be seen on Eureka after successful startup:

  • When the browser accesses the Web interface provided by Cloud-client-side, the response is as follows, indicating that Cloud-client-side successfully invokes the gRPC service of Cloud-server-Side:

A little bit confused

  • If you know anything about Eureka, you might be a little confused: Cloud-client-side Cloud-server-side information obtained from Eureka should be HTTP service address and port, should not have gRPC port number, because Eureka registration discovery service does not include gRPC!

  • Space is limited, here is not suitable for the analysis of the above problems, let’s focus on the most core place, I believe that smart you will suddenly see;

  • DiscoveryClientNameResolver from GRPC – the client – spring – the boot – autoconfigure. Jar, used to store the information obtained from eureka server-side, annotation of the class has already said very clearly, Obtain the gRPC port number from the grpc. port configuration item of metadata:

  • In the code of DiscoveryClientNameResolver hit a breakpoint, view the member variables instanceList, really have the gRPC port of the visible metadata information:

  • As for the cloud – server – side how to port number to had been submitted, and the cloud – the client – side why use DiscoveryClientNameResolver to deal with the information service list, had not discussed in this article, If you are interested in exploring Eureka in depth, you can refer to the Eureka source code analysis topic in Programmer Chen’s Spring Article.

  • At this point, the development and verification of EUreka based gRPC service registration discovery has been completed. I hope this article can bring you some references to make your service more flexible and reliable under the support of the registry.

You are not alone, Xinchen original accompany all the way

  1. Java series
  2. Spring series
  3. The Docker series
  4. Kubernetes series
  5. Database + middleware series
  6. The conversation series

Welcome to pay attention to the public number: programmer Xin Chen

Wechat search “programmer Xin Chen”, I am Xin Chen, looking forward to enjoying the Java world with you…

Github.com/zq2599/blog…