This is my 18th day of the Genwen Challenge

1.RPC

1. The introduction of the RFC

Request For Comments (RFC) is a series of numbered files. The file collects information about the Internet, as well as software files for the UNIX and Internet communities. The RFC file is sponsored and distributed by the Internet Society (ISOC). Basic Internet communication protocols are specified in RFC files. The RFC document also adds many additional topics within the standard, such as new protocols developed for the Internet and all records in development. So almost all Internet standards are included in RFC documents.

RPC collects RFC 1831. It can be viewed at the following url:

Datatracker.ietf.org/doc/rfc1831…

2.RPC

1. The RPC is what

Remote Procedure Call Protocol (RPC) is a Protocol that requests services from Remote computer programs over the network without understanding the underlying network technology. In short, RPC enables programs to access remote system resources just as they access local system resources. Some of the key aspects include: communication protocol, serialization, resource (interface) description, service framework, performance, language support, etc.

2. Why is RPC needed

So what problem did the advent of RPC solve? What benefits did it bring

1. Single application architecture

When site traffic is low, only one application is needed to deploy all functions together to reduce deployment nodes and costs. At this point, data access frameworks (ORM) that simplify the work of adding, deleting, modifying and reviewing are key.

2. Vertical application architecture

When the volume of traffic gradually increases, the acceleration caused by the increase of a single application machine is getting smaller and smaller. The application is divided into several unrelated applications to improve efficiency. At this point, a Web framework (MVC) for accelerating front-end page development is key.

3. Distributed service architecture

With the increasing number of vertical applications, the interaction between applications is inevitable. Core businesses are extracted as independent services, gradually forming a stable service center, so that front-end applications can respond to changing market demands more quickly.

At this point, the distributed services framework (RPC) for improving service reuse and integration is the key to provide unified services.

For example, the service providers of each team should not implement a set of serialization, deserialization, network framework, connection pool, sending and receiving threads, timeout processing, state machines and other “out-of-business” repetitive technical labor, resulting in overall inefficiency.

Mobile Computing Architecture

PS: This is an extension, taken from the Dubbo website, and is part of an architectural evolution

As the number of services increases, problems such as capacity evaluation and waste of small service resources gradually emerge. In this case, a scheduling center needs to be added to manage cluster capacity in real time based on access pressure to improve cluster utilization. At this point, a resource scheduling and Governance center (SOA) for improving machine utilization is key.

4. Another reason

This is because memory space cannot be shared within several processes (applications are distributed on different machines), or related requirements such as communication between different systems or even between different organizations cannot be fulfilled through local calls within a single machine. In addition, due to the horizontal scaling of machines, applications need to be deployed on clusters of multiple machines, and so on.

Therefore, unified RPC framework to solve the problem of providing unified services.

3. Introduction

As mentioned earlier, the RPC protocol allows one host program over the Internet to call another host program without the programmer having to program the interaction. It is emphasized in RPC protocol that when A program calls functions or methods in B program, A does not know the specific implementation of methods in B.

RPC is an upper layer protocol, and the lower layer is based on TCP or HTTP. In general, RPC is based on a concrete implementation of RPC. Such as the Double frame. In a broad sense, all calls that meet the requirements of network communication are called RPC. Even HTTP is a concrete implementation of RPC. However, from a concrete analysis, RPC protocol is more efficient than HTTP protocol, and rPC-based framework has more functions.

3. Comparison between HTTP and RPC

1. Specific and approximate implementation:

1.RPC: It can be implemented based on TCP or HTTP. In fact, B belongs to RPC as long as it conforms to service call A

2.HTTP: based on HTTP

The efficiency of 2.

1.RPC: Customized implementation reduces unnecessary packet content and makes packet volume smaller

2.HTTP: If it is HTTP1.1, much of the content in its message is useless. If it is not much different from RPC after HTTP2.0, what is missing is some service governance features of RPC.

So the efficiency difference is mainly based on HTTP1.1

3. Connection mode

1.RPC: long link

2.HTTP: Each connection is a three-way handshake

4. Performance:

1.RPC can be serialized in many ways. Such as: thrift

2.HTTP is mainly serialized and deserialized through JSON, which is inefficient

5. Registry

1.RPC: Common RPC frameworks come with registries

2.HTTP: Direct connection

6. Load balancing

1. Most RPC frameworks come with load balancing measurements

2.HTTP: Third-party tools are generally required. Such as Nginx

Summary:

RPC generally has rich governance functions and is more suitable for interface invocation within the enterprise. HTTP is better suited for cross-platform calls

2.HttpClient

1. Introduction of HttpClient

We know that the Java.NET package in Java provides the basic functions of user Http access, but it is not so flexible to use and with the development of technology, its functions have been unable to meet the needs of applications. So HttpClient came along.

HttpClient is a subproject of Apache Jakarta Common that provides an efficient, up-to-date, feature-rich client programming toolkit that supports the latest versions and recommendations of the HTTP protocol. HttpClient has been used in many projects, such as Cactus and HTMLUnit, two other well-known open source projects on Apache Jakarta that use HttpClient. The Commons HttpClient project has been terminated and is no longer under development. It has been replaced by the HttpClient and HttpCore modules in the Apache HttpComponents project, which provide better performance and greater flexibility.

2. Code implementation

1. Server code

1. Create a Springboot project and add the SpringBoot-Web plug-in, or do not add it and add it yourself in pom.xml

2. Create the Controller layer to verify whether the service is callable

@Controller
public class deomController {

    @RequestMapping("/demo")
    @ResponseBody
    public String demo(String param){
        return param+"---abc"; }}Copy the code

Start project access demo and parameters, call success

2. Create a client call

1. Create a Maven project

2. Add the HttpClient dependency

    <dependencies>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.513.</version>
        </dependency>
    </dependencies>
Copy the code

1. Two call methods

1. The Get method requests access
@Test
public void GetDemo(a) throws Exception{
    //1. Create a utility class (equivalent to a browser) to send the request and parse the response
    CloseableHttpClient httpClient = HttpClients.createDefault();
    //2. Set the request path and encapsulate the path as the URIBuilder object
    URIBuilder uriBuilder = new URIBuilder("http://localhost:8080/demo? param=zhangsan");
    //2.1 Adding parameters One can be added directly through a link, and the other is the following, which is in the form of key-value pairs
    uriBuilder.addParameter("param"."zhangsan");
    //3. Create an httpGet request object
    HttpGet httpGet = new HttpGet(uriBuilder.build());
    //4. Create response objects
    CloseableHttpResponse response = httpClient.execute(httpGet);
    //5. Since the response object is a string, we need to convert the HttpEntity type to a string type and set the character set encoding
    String result = EntityUtils.toString(response.getEntity(), "utf-8");
    //6. Output the result
    System.out.println(result);
    //7. Release resources
    httpClient.close();
    response.close();
}
Copy the code
2. The Post method requests access
@Test
public void PostDemo(a) throws Exception {
    //1. Create a tool class.
    CloseableHttpClient httpClient = HttpClients.createDefault();
    //2. Set the request path
    HttpPost httpPost = new HttpPost("http://localhost:8080/demo");
    //2.1 Put parameters in the POST request
    List<NameValuePair> params = new ArrayList<>();
    params.add(new BasicNameValuePair("param"."zhangsan"));
    //2.2 Create a text implementation class object for the HttpEntity interface, place your parameters and set the encoding
    HttpEntity httpEntity = new UrlEncodedFormEntity(params, "utf-8");
    //2.3 Put it into an httpPost object
    httpPost.setEntity(httpEntity);

    //3. Create a response object to initiate the request
    CloseableHttpResponse response = httpClient.execute(httpPost);
    //4. Return a structure to convert the Entity type to a String
    String result = EntityUtils.toString(response.getEntity(), "utf-8");
    //5. Print the result
    System.out.println(result);
    //6. Release resources
    response.close();
    httpClient.close();
}
Copy the code

2. Server-side data format encapsulation (JSON)

Verify server-side tests

Start by creating a User object

public class User {
    private Integer id;
    private String name;
    private String age;

    public User(a) {}public User(Integer id, String name, String age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    public Integer getId(a) {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName(a) {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAge(a) {
        return age;
    }

    public void setAge(String age) {
        this.age = age; }}Copy the code

The client gets the result

@Test public void testObjectPostdemo(){ //1. The above steps to create a utility class CloseableHttpClient httpClient = HttpClients. CreateDefault (); / / 2. Create an HttpPost request object HttpPost HttpPost = new HttpPost (" http://localhost:8080/demo2 "); List<NameValuePair> parms = new ArrayList<>(); parms.add(new BasicNameValuePair("id","1")); parms.add(new BasicNameValuePair("age", "20")); Add (new BasicNameValuePair("name", "name")); //4. Set parameter encoding try {HttpEntity HttpEntity = new UrlEncodedFormEntity(parms, "UTF-8 "); //4.1 Place the populated Entity object in the request httpPost.setentity (httpEntity); CloseableHttpResponse Response = httpClient.execute(httpPost); //4.3 Converting the returned result set to a String String result = Entityutils.toString (Response.getentity ()); System.out.println(result); }catch(Exception e){ e.printStackTrace(); }finally { try { httpClient.close(); } catch (IOException e) { e.printStackTrace(); }}}Copy the code

The server code is as follows:

@RequestMapping("/demo2")
@ResponseBody
public User demo2(User user){
    return user;
}
Copy the code

3. The use of JackSon

Add the dependent

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.11.4</version>
</dependency>
Copy the code

To return the string of the response to an object and populate the object’s properties, JackSon is required

@Test
public void testObjectPostdemo(a){
    //1. Repeat the preceding steps to create a tool class
    CloseableHttpClient httpClient = HttpClients.createDefault();
    //2. Create an HttpPost request object
    HttpPost httpPost = new HttpPost("http://localhost:8080/demo2");
    //3. Create parameters
    List<NameValuePair> parms = new ArrayList<>();
    parms.add(new BasicNameValuePair("id"."1"));
    parms.add(new BasicNameValuePair("age"."20"));
    parms.add(new BasicNameValuePair("name"."Where the hell is zhang?"));

    //4. Set the parameter encoding
    try {
        HttpEntity httpEntity = new UrlEncodedFormEntity(parms, "utf-8");
        //4.1 Place the filled Entity object in the request
        httpPost.setEntity(httpEntity);
        4.2 Executing the POST request
        CloseableHttpResponse response = httpClient.execute(httpPost);
        //4.3 Convert the returned result set to a string
        String result = EntityUtils.toString(response.getEntity());
        System.out.println(result);

        // Use JackSon to convert characters to objects
        ObjectMapper objectMapper = new ObjectMapper();
        User user = objectMapper.readValue(result, User.class);
        System.out.println(user);

        String restring = objectMapper.writeValueAsString(user);
        System.out.println(restring);

    }catch(Exception e){
        e.printStackTrace();
    }finally {
        try {
            httpClient.close();
        } catch(IOException e) { e.printStackTrace(); }}}Copy the code

4. Collection types

The key is the use of these two pieces of code

// How do I convert a collection to JSON
ObjectMapper objectMapper = new ObjectMapper();
// Convert User to List, a collection class
JavaType javaType = objectMapper.getTypeFactory().constructParametricType(List.class, User.class);
Copy the code

The complete client code is as follows:

@Test
public void test(a) throws Exception{
    CloseableHttpClient httpClient = HttpClients.createDefault();
    HttpPost post = new HttpPost("http://localhost:8080/demo3");
    CloseableHttpResponse response = httpClient.execute(post);

    String result = EntityUtils.toString(response.getEntity(), "utf-8");
    System.out.println(result);

    // How do I convert a collection to JSON
    ObjectMapper objectMapper = new ObjectMapper();
    // Convert User to List
    JavaType javaType = objectMapper.getTypeFactory().constructParametricType(List.class, User.class);
    // Now you can use it
    List<User> list = objectMapper.readValue(result, javaType);
    System.out.println(list);

    httpClient.close();
}
Copy the code

The server code is as follows:

@RequestMapping("/demo3")
@ResponseBody
public List<User> demo(a){
    List<User> list = new ArrayList<>();
    list.add(new User(1."Three points."."24"));
    list.add(new User(1."Zhang"."24"));
    list.add(new User(1."Zhang points"."24"));

    // Finally return a collection directly
    return list;
}
Copy the code

5. Flow type

Server code

@RequestMapping("/demo4")
@ResponseBody
// You need to add the @requestBody annotation to parse the JSON data from the client
public String demo(@RequestBody List<User> list){ 
    System.out.println(list);
    return list.toString();
}
Copy the code

Client:

@Test
public void testIputStresm(a){
    //1. Create a tool class
    CloseableHttpClient httpClient = HttpClients.createDefault();
    //2. Create a request class and specify a request path
    HttpPost post = new HttpPost("http://localhost:8080/demo4");
    //3. Execute the request, because the parameters passed are a List collection, so we need to create a collection
    List<User> listParam = new ArrayList<>();
    listParam.add(new User(1."zhangsan"."23"));
    listParam.add(new User(1."zhisan"."23"));
    listParam.add(new User(1."zhang"."23"));

    // Convert the collection to JSON
    ObjectMapper objectMapper = new ObjectMapper();
    try {
        String result = objectMapper.writeValueAsString(listParam);
        System.out.println(result);

        // Convert the JSON to an object
        HttpEntity httpEntity = new StringEntity(result, ContentType.APPLICATION_JSON);
        post.setEntity(httpEntity);

        CloseableHttpResponse response = httpClient.execute(post);
        String strresult = EntityUtils.toString(response.getEntity());

        System.out.println(strresult);

        response.close();
        httpClient.close();
    } catch(Exception e) { e.printStackTrace(); }}Copy the code

6. Ajax requests

The server request code is the same as the service code for the above flow type

Then import the front end file and write the front end code Ajax to send the request

<! DOCTYPEhtml>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript" src="/ js/jquery - 1.7.2. Js"></script>
    <script type="text/javascript">

        $(function () {$("button").click(function(){

                var json = '[{"id":123,"name":"msb"},{"id":456,"name":"mashibing"}]';

                $.ajax({
                    url:'http://localhost:8080/demo5'.type:'post'.success:function (data) {
                        for(var i = 0 ; i<data.length ; i++)
                        {
                            alert(data[i].id +""+ data[i].name); }},contentType:'application/json'.// The content type in the request body
                    dataType:'json'.// Response content type
                    data:json
                });
            });
        });

    </script>
</head>
<body>
    <button>button</button>
</body>
</html>
Copy the code

7.Ajax cross-domain requests

Cross – domain request: any difference in protocol, IP, or port is a cross – domain request.

Same-origin policy: By default, the browser allows Ajax to access only same-origin content (with the same protocol, IP address, and port).

Resolve the same Origin policy:

Add @crossorigin to the controller interface. Indicates that cross-domain is allowed. Add access-Control-allow-origin: * to the response header

3. RMI

Remote Method Invocation (RMI).

RMI is a feature from JDK1.2 that allows one Java application to call content in a Java application (JVM) on another server as if it were a local method.

RMI is a remote call to the Java language and cannot be implemented across languages. The flow chart is as follows:

[Img-eaga1VP5-1616204980574] (F: MyFile/Study Notes/Java study Notes / 11.distributed / 11.Image material / 25.rpc-03.png) [IMG – Eaga1VP5-1616204980574]

1.Remote

Java.rmi. Remote defines this interface as a Remote invocation interface. If an interface is called externally, you need to inherit this interface.

public interface Remote{}
Copy the code

2. RemoteException

java.rmi.RemoteException

An interface that inherits the Remote interface needs to throw this exception if a method is allowed to be called remotely.

3.UnicastRemoteObject

java.rmi.registry.LocateRegistry

The Registry can be created on the local machine using LocateRegistry and is accessible through a specific port.

4.Naming

java.rmi.Naming

Naming defines the RMI name accessible to published content. Obtaining the specified remote method also using Naming.

5. Code implementation

1. The server creates a code block

1. Interface creation:

public interface DemoService extends Remote {
    RemoteException needs to be thrown because the method needs to be called remotely
    String demo(String param) throws RemoteException;
}
Copy the code

2. Interface implementation:

public class DemoServiceImpl extends UnicastRemoteObject implements DemoService {

    // Since the constructor of the parent UnicastRemoteObject class is protected, the constructor will be upgraded
    public DemoServiceImpl(a) throws RemoteException{}

    @Override
    public String demo(String param) throws RemoteException {
        return param+"abc"; }}Copy the code

3. Demo of the server supports access

public class DemoServer {
    public static void main(String[] args) throws Exception{
        1. Create an interface instance
        DemoService demoService = new DemoServiceImpl();
        Create a registry
        LocateRegistry.createRegistry(8989);
        //3. Bind services
        Naming.bind("rmi://localhost:8989/demoService", demoService);

        System.out.println("Server started successfully"); }}Copy the code
2. Create the client calling code
public class ClientDemo {

    public static void main(String[] args) throws Exception{
        // The client registers information with the server and returns the Remote type
        // But the DemoService type is actually called, so it will
        // Add client project to module
        // Add the server dependency to the client
        DemoService demoService = (DemoService) Naming.lookup("rmi://localhost:8989/demoService");
        String result = demoService.demo("zhangsan"); System.out.println(result); }}Copy the code

In this course, the code conversion of the server side is directly copied, or it is not necessary to directly use the server as the medium project, and then add the client project through IDEA, and import the client project into the module in the project structure. Then add the dependencies as the code says

<dependency>
    <groupId>com.anzhi</groupId>
    <artifactId>rmirpc</artifactId>
    <version>0.0.1 - the SNAPSHOT</version>
</dependency>
Copy the code

The code is then executed, starting the server before doing so, which implements the RPC call to RMI