What are microservices

  • Microservice architecture is a distributed system, which is divided into different service units based on services to solve the performance deficiencies of single systems.
  • Microservices is an architectural style in which a large software application consists of multiple units of services. Service units in the system can be deployed separately and are loosely coupled.

Origin of Microservices concept: Microservices

How do microservices communicate independently

synchronous

REST the HTTP protocol

REST requests are the most common communication method in microservices and rely on the HTTP\HTTPS protocol. RESTFUL features are:

  1. Each URI represents one resource
  2. The client uses GET, POST, PUT, and DELETE to operate on server resources. GET is used to obtain resources, POST is used to create resources (or update resources), PUT is used to update resources, and DELETE is used to DELETE resources
  3. Manipulate a resource by manipulating its representation
  4. Resources are represented in XML or HTML
  5. The interaction between client and server is stateless between requests, and each request from client to server must contain the information necessary to understand the request

For example, a service provider provides the following interface:

@RestController
@RequestMapping("/communication")
public class RestControllerDemo {
    @GetMapping("/hello")
    public String s(a) {
        return "hello"; }}Copy the code

Another service needs to invoke this interface, and the caller simply sends the request according to the API documentation to get the result returned.

@RestController
@RequestMapping("/demo")
public class RestDemo{
    @Autowired
    RestTemplate restTemplate;

    @GetMapping("/hello2")
    public String s2(a) {
        String forObject = restTemplate.getForObject("http://localhost:9013/communication/hello", String.class);
        returnforObject; }}Copy the code

In this way, services can communicate with each other.

RPC TCP protocol

Remote Procedure Call (RPC). Simply understood, a node requests services provided by another node. It works like this:

  1. Execute the client call statement and pass the parameters
  2. Calls the local system to send network messages
  3. The message is sent to the remote host
  4. The server gets the message and gets the parameters
  5. Perform remote procedures (services) based on invocation requests and parameters
  6. The result is returned to the server handle when the process is complete
  7. The server handle returns the result, and the system network service that calls the remote host sends the result
  8. The message is sent back to the local host
  9. The client handle receives messages from the local host’s network service
  10. The client receives the result data returned by the calling statement

Let me give you an example.

First you need a server:

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Method;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/** * The interface and implementation class used by the RPC server to register remote methods */
public class RPCServer {
    private static ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());

    private static final ConcurrentHashMap<String, Class> serviceRegister = new ConcurrentHashMap<>();

    /** * Registration method *@param service
     * @param impl
     */
    public void register(Class service, Class impl) {
        serviceRegister.put(service.getSimpleName(), impl);
    }

    /** * Start method *@param port
     */
    public void start(int port) {
        ServerSocket socket = null;
        try {
            socket = new ServerSocket();
            socket.bind(new InetSocketAddress(port));
            System.out.println("Service startup");
            System.out.println(serviceRegister);
            while (true) {
                executor.execute(newTask(socket.accept())); }}catch (Exception e) {
            e.printStackTrace();
        } finally {
            if(socket ! =null) {
                try {
                    socket.close();
                } catch(IOException e) { e.printStackTrace(); }}}}private static class Task implements Runnable {
        Socket client = null;

        public Task(Socket client) {
            this.client = client;
        }

        @Override
        public void run(a) {
            ObjectInputStream input = null;
            ObjectOutputStream output = null;
            try {
                input = new ObjectInputStream(client.getInputStream());
                // Read the contents in orderString serviceName = input.readUTF(); String methodName = input.readUTF(); Class<? >[] parameterTypes = (Class<? >[]) input.readObject(); Object[] arguments = (Object[]) input.readObject(); Class serviceClass = serviceRegister.get(serviceName);if (serviceClass == null) {
                    throw new ClassNotFoundException(serviceName + "Nothing!");
                }
                Method method = serviceClass.getMethod(methodName, parameterTypes);
                Object result = method.invoke(serviceClass.newInstance(), arguments);

                output = new ObjectOutputStream(client.getOutputStream());
                output.writeObject(result);
            } catch (Exception e) {
                e.printStackTrace();

            } finally {
                try {
                    // Do not write output! =null to turn off this logic
                    output.close();
                    input.close();
                    client.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
        }
    }

}

Copy the code

Second, you need a client:

import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.net.InetSocketAddress;
import java.net.Socket;

/** * RPC client */
public class RPCclient<T> {
    /** * Sends parameters to RPCServer via dynamic proxy, and RPCServer returns the result. This method is processed as the correct entity */
    public static <T> T getRemoteProxyObj(final Class<T> service, final InetSocketAddress addr) {

        return (T) Proxy.newProxyInstance(service.getClassLoader(), newClass<? >[]{service},new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

                Socket socket = null;
                ObjectOutputStream out = null;
                ObjectInputStream input = null;
                try {
                    socket = new Socket();
                    socket.connect(addr);

                    // Send the entity class, parameters, to the remote caller
                    out = new ObjectOutputStream(socket.getOutputStream());
                    out.writeUTF(service.getSimpleName());
                    out.writeUTF(method.getName());
                    out.writeObject(method.getParameterTypes());
                    out.writeObject(args);

                    input = new ObjectInputStream(socket.getInputStream());
                    return input.readObject();
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    out.close();
                    input.close();
                    socket.close();
                }
                return null; }}); }}Copy the code

Let’s test one more remote method.

public interface Tinterface {
    String send(String msg);
}

public class TinterfaceImpl implements Tinterface {
    @Override
    public String send(String msg) {
        return "send message "+ msg; }}Copy the code

The test code is as follows:

import com.huifer.admin.rpc.Tinterface;
import com.huifer.admin.rpc.TinterfaceImpl;

import java.net.InetSocketAddress;

public class RunTest {
    public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run(a) {
                RPCServer rpcServer = new RPCServer();
                rpcServer.register(Tinterface.class, TinterfaceImpl.class);
                rpcServer.start(10000);
            }
        }).start();
        Tinterface tinterface = RPCclient.getRemoteProxyObj(Tinterface.class, new InetSocketAddress("localhost".10000));
        System.out.println(tinterface.send("RPC Test Case")); }}Copy the code

Output the Send Message RPC test case.

asynchronous

Message middleware

Common messaging-oriented middleware include Kafka, ActiveMQ, RabbitMQ, RocketMQ, and common protocols include AMQP, MQTTP, STOMP, and XMPP. Message queues are not extended here, please visit the official website for details.

Link: What are microservices? How do microservices communicate independently? Source: making