An overview,

Remote Procedure Call (RPC) refers to how a node requests a service provided by another node. Build a simulated call chain in the micro service call chain tracking center: ServiceA –> ServiceB –> ServiceC is an example of remote invocation, but this article uses the RestTemplate method of synchronous invocation, using the HTTP protocol at the application layer, although this method works, but sometimes not very efficient. RPC, however, does not depend on application-layer protocols, can make remote calls directly based on TCP, and the communication can be completed at the transport layer. Therefore, RPC is more suitable for some scenarios that require higher efficiency. Because RPC calls rely on the Socket connection between the client and the server to achieve binary data communication, the underlying layer is relatively complex. Therefore, some RPC frameworks have emerged to encapsulates this complexity, allowing developers to focus on business. Common RPC frameworks include Thrift, gRPC, Finagle, Dubbo, and so on. Starting with this article, THE author will choose some of them to practice. This article mainly records the author’s practice process with the Thrift framework.

Thrift is an Apache project that combines a powerful software stack and code generation engine to provide seamless support across many languages.

Move as action!

Note: This article is published on My official account CodeSheep. You can long press or scan the following note to subscribe ↓ ↓


Ii. Experimental environment

  • Mac OS X 10.13.2
  • SpringBoot 2.0.1
  • Thrift 0.11.0
  • IDE: IntelliJ IDEA 2018.01

In order to facilitate readers’ understanding, I will first summarize the following content, including 7 points:

  • Thrift environment construction
  • Thrift plug-in configuration in IDEA
  • Create a Thrift project and compile it (purpose: to define an RPC interface)
  • Develop the Thrift API interface
  • Develop the RPC server
  • Develop an RPC client
  • Practical experiment of RPC communication

Third, Thrift environment construction

  • ** Method 1: ** Native installation, through the official steps to install step by step

See here: Thrift official Installation Tutorial for Mac

  • ** Method 2: ** Use BREW tool (recommended)

brew install thrift


Configuration of Thrift plug-in in IDEA

Method 1: Configure the IP address on the IDEA interface

Open IDEA’s plug-in center and search for Thrift to install

Method two: manually download the Thrift plug-in and install it

Just like installing the Lombok plug-in in IDEA in SpringBoot’s Elegant Coding: Lombok Plus article, there are times when the plug-in cannot be installed due to network reasons when method 1 does not work. In this case, you can manually download the plug-in and install it.

Can go to the following address download Thrift plug-in: http://plugins.jetbrains.com/plugin/7331-thrift-support

Install plugin from disk… Select the downloaded ZIP package to install, and then restart the IDE

A sign of success is the presence of a Thrift Compiler in the Compiler! As shown in the figure below:


Create and compile the Thrift Project (define RPC interface)

  • Step 1: Create the Thrift project and configure it

The IDE is smart enough to provide Thrift Project creation options in the New Project:

After the Project is created, set the Thrift configuration of Facets in the Project Settings, as shown in the figure below, where we add a Java Generator

In the dialog box that pops up, configure the Output Folder path to store the Java source files converted from thrift files:

OK, the Thrift project is ready!

  • Step 2: Create the Thrift interface file

Here create a Thrift interface file: RPCDateService. Thrift

The thrift file is written in a way that I won’t go into detail. Like gRPC, it has its own syntax, and namespace is the package name of the interface file that is generated

namespace java com.hansonwang99.thrift.interface
service RPCDateService{
    string getDate(1:string userName)
}
Copy the code

In this interface file, we define a Service that provides a date for the client to query the current time of the server through this interface

  • Step 3: Compile the Thrift source file to generate the Java interface classes

Right click on the. Thrift source file and click Recompile ‘xxx.thrift’ to complete the conversion of thrift interface files –> Java interface files

The output Java interface file is generated in the output configured above, and its package structure is equal to the namespace in the above. Thrift file. The package structure is shown in the following figure.


Develop Thrift API interfaces

Let’s create a Maven project: ThriftAPI that contains the Java interface generated by the custom Thrift interface above: the rpcDateservice.java file that will be used for the subsequent RPC server and RPC client code implementations!

  • Add thrift dependencies to POM.xml
<dependencies> <dependency> <groupId>org.apache.thrift</groupId> <artifactId>libthrift</artifactId> The < version > 0.11.0 < / version > < / dependency > < / dependencies >Copy the code
  • Add RPCDateService. Java

Rpcdateservice. Java generated by rpcDateservice. thrift in step 5 above is copied to the Maven project as is.

Again, this ThriftAPI project will serve the RPC servers and RPC clients that you will create below


Develop RPC server

We use SpringBoot to implement the RPC server

  • Add dependencies to POM.xml

In addition to the automatically added SpringBoot dependencies, you need to add the ThriftAPI dependencies above

< the dependency > < groupId > com. Hansonwang99 < / groupId > < artifactId > ThriftAPI < / artifactId > < version > 1.0 - the SNAPSHOT < / version > </dependency>Copy the code
  • Create the Controller and implement the RPC interface
@Controller
public class RPCDateServiceImpl implements RPCDateService.Iface {
    @Override
    public String getDate(String userName) throws TException {
        Date now=new Date();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("Today is"+Yyyy year MM Month DD day E KK point MM minute);
        String nowTime = simpleDateFormat.format( now );
        return "Hello " + userName + "\n"+ nowTime; }}Copy the code

The current server time is returned to the caller as a string!

  • Write RPCThriftServer: to start the RPC server
@Component
public class RPCThriftServer {
    protected final Logger logger = LoggerFactory.getLogger(this.getClass());
    @Value("${thrift.port}")
    private int port;
    @Value("${thrift.minWorkerThreads}")
    private int minThreads;
    @Value("${thrift.maxWorkerThreads}")
    private int maxThreads;

    private TBinaryProtocol.Factory protocolFactory;
    private TTransportFactory transportFactory;

    @Autowired
    private RPCDateServiceImpl rpcDateService;

    public void init() {
        protocolFactory = new TBinaryProtocol.Factory();
        transportFactory = new TTransportFactory();
    }

    public void start() {
        RPCDateService.Processor processor = new RPCDateService.Processor<RPCDateService.Iface>( rpcDateService );
        init();
        try {
            TServerTransport transport = new TServerSocket(port);
            TThreadPoolServer.Args tArgs = new TThreadPoolServer.Args(transport);
            tArgs.processor(processor);
            tArgs.protocolFactory(protocolFactory);
            tArgs.transportFactory(transportFactory);
            tArgs.minWorkerThreads(minThreads);
            tArgs.maxWorkerThreads(maxThreads);
            TServer server = new TThreadPoolServer(tArgs);
            logger.info("Thrift service started successfully, port ={}", port);
            server.serve();
        } catch (Exception e) {
            logger.error("Thrift service failed to start", e); }}}Copy the code
  • Create SpringBootApplication
@SpringBootApplication public class RPCThriftServerApplication { private static RPCThriftServer rpcThriftServer; public static void main(String[] args) { ApplicationContext context = SpringApplication.run(RPCThriftServerApplication.class, args); try { rpcThriftServer = context.getBean(RPCThriftServer.class); rpcThriftServer.start(); } catch (Exception e) { e.printStackTrace(); }}}Copy the code
  • Add the configuration file application.properties
thrift.port=6666
thrift.minWorkerThreads=10
thrift.maxWorkerThreads=100
Copy the code

We have thrift service starting at port 6666!

  • Start the RPC server service


Develop RPC client

Here also uses SpringBoot to implement RPC client!

  • Add dependencies to POM.xml

    This depends on the RPC server and is not described here

  • Write RPCThriftClient: for making RPC calls

This contains two files: RPCThriftClient. Java and RPCThriftClientConfig. Java

RPCThriftClient. Java is as follows:

public class RPCThriftClient {
    private RPCDateService.Client client;
    private TBinaryProtocol protocol;
    private TSocket transport;
    private String host;
    private int port;

    public String getHost() {
        return host;
    }
    public void setHost(String host) {
        this.host = host;
    }
    public int getPort() {
        return port;
    }
    public void setPort(int port) {
        this.port = port;
    }

    public void init() {
        transport = new TSocket(host, port);
        protocol = new TBinaryProtocol(transport);
        client = new RPCDateService.Client(protocol);
    }

    public RPCDateService.Client getRPCThriftService() {
        return client;
    }

    public void open() throws TTransportException {
        transport.open();
    }

    public void close() { transport.close(); }}Copy the code

While RPCThriftClientConfig. Java beans generated by the config

@Configuration
public class RPCThriftClientConfig {
    @Value("${thrift.host}")
    private String host;
    @Value("${thrift.port}")
    private int port;

    @Bean(initMethod = "init")
    public RPCThriftClient rpcThriftClient() {
        RPCThriftClient rpcThriftClient = new RPCThriftClient();
        rpcThriftClient.setHost(host);
        rpcThriftClient.setPort(port);
        returnrpcThriftClient; }}Copy the code
  • Write a Restful Controller as an entry point
@RestController
@RequestMapping("/hansonwang99")
public class RPCThriftContoller {
    protected final Logger logger = LoggerFactory.getLogger(this.getClass());
    @Autowired
    private RPCThriftClient rpcThriftClient;

    @RequestMapping(value = "/thrift", method = RequestMethod.GET)
    public String thriftTest(HttpServletRequest request, HttpServletResponse response) {
        try {
            rpcThriftClient.open();
            return rpcThriftClient.getRPCThriftService().getDate("hansonwang99");
        } catch (Exception e) {
            logger.error("RPC call failed", e);
            return "error"; } finally { rpcThriftClient.close(); }}}Copy the code
  • Create SpringBootApplication
@SpringBootApplication public class RPCThriftClientApplication { public static void main(String[] args) { SpringApplication.run(RPCThriftClientApplication.class, args); }}Copy the code
  • Add the configuration file application.properties
thrift.host=localhost
thrift.port=6666
server.port=9999
Copy the code
  • Example Start the RPC client service


9. RPC communication experiment

Our browser input: localhost: 9999 / hansonwang99 / thrift can view the client from the server to retrieve the current server time, explain the process of RPC communication through!


Ten, afterword.

The experimental code in this paper has been open source, click to obtain

  • More of the author’s original articles here, welcome to watch

  • My Personal Blog

The author’s more SpringBt practice articles are here:

  • Spring Boot application monitoring in action
  • The SpringBoot application is deployed in an external Tomcat container
  • ElasticSearch search engine in SpringBt practice
  • Preliminary study on Kotlin+SpringBoot joint programming
  • Spring Boot Logging framework practices
  • SpringBoot Elegant Coding: Lombok Blessing

If you are interested, you can also take a look at some of the author’s articles on containerization and microservitization:

  • Using K8S technology stack to build personal private cloud serials
  • Detail the Nginx server configuration from a configuration list
  • Construction of visual monitoring center of Docker container
  • Build the Docker container application log center with ELK
  • RPC framework practice: Apache Thrift
  • RPC Framework Practice: Google gRPC
  • Set up tracing center of microservice invocation chain
  • Docker containers communicate across hosts
  • Preliminary study on Docker Swarm cluster
  • A few guidelines for writing Dockerfiles efficiently