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:
- Each URI represents one resource
- 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
- Manipulate a resource by manipulating its representation
- Resources are represented in XML or HTML
- 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:
- Execute the client call statement and pass the parameters
- Calls the local system to send network messages
- The message is sent to the remote host
- The server gets the message and gets the parameters
- Perform remote procedures (services) based on invocation requests and parameters
- The result is returned to the server handle when the process is complete
- The server handle returns the result, and the system network service that calls the remote host sends the result
- The message is sent back to the local host
- The client handle receives messages from the local host’s network service
- 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