How to design a registration center? (2) Implement registration interface

1. Create SpringBoot project

Create a parent project and three sub-modules, one of which serves as the registration center and the other two serve as service providers.
Insert image description here
pom

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>registerTest</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>server</module>
        <module>provider1</module>
        <module>provider2</module>
    </modules>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.1.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.1.23</version>
        </dependency>
    </dependencies>

</project>

2. Implement http access

Note: Currently, synchronous requests are used here, but asynchronous requests are actually more appropriate.

package http.client;

import com.alibaba.fastjson.JSONObject;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;

public class HttpClient {
    
    
    private String url;
    private String contentType;
    private String encoding;
    private JSONObject data;

    public HttpClient(String url, String encoding, String contentType, JSONObject data) {
    
    
        this.url = url;
        this.data = data;
        this.encoding = encoding == null ? "UTF-8" : encoding;
        this.contentType = contentType == null ? "application/json" : contentType;
    }

    public JSONObject httpGet() throws Exception {
    
    
        try (CloseableHttpClient httpClient = HttpClientBuilder.create().build()) {
    
    
            HttpGet httpGet = new HttpGet(url);
            HttpResponse response = httpClient.execute(httpGet);
            if (response.getStatusLine().getStatusCode() != 200) {
    
    
//            throw new Exception("调用服务端异常.");
                return getResult(false, "调用服务端异常.");
            }
            HttpEntity res = response.getEntity();
            String resultData = EntityUtils.toString(res);
            System.out.println("从服务端返回结果: " + resultData);
            return JSONObject.parseObject(resultData);
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
        return getResult(false, "");
    }

    public JSONObject httpPost() throws Exception {
    
    
        try (CloseableHttpClient httpClient = HttpClientBuilder.create().build()) {
    
    
            String json = JSONObject.toJSONString(data);
            StringEntity entity = new StringEntity(json);
            entity.setContentEncoding(encoding);
            entity.setContentType(contentType);
            HttpPost httpPost = new HttpPost(url);
            httpPost.setEntity(entity);
            HttpResponse response = httpClient.execute(httpPost);
            if (response.getStatusLine().getStatusCode() != 200) {
    
    
                return getResult(false, "调用服务端异常.");
            }
            HttpEntity res = response.getEntity();
            String resultData = EntityUtils.toString(res);
            System.out.println("从服务端返回结果: " + resultData);
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
        return getResult(false, "");
    }

    public static JSONObject getResult(boolean res, String msg) {
    
    
        return new JSONObject(){
    
    {
    
    
            put("res", res);
            put("msg", msg);
        }};
    }
}

Implement a simple registry structure that represents the name and IP of the module

package common;

public class RegisterTable {
    
    
    private String name;
    private String ip;

    public RegisterTable(String name, String ip) {
    
    
        this.name = name;
        this.ip = ip;
    }

    public String getIp() {
    
    
        return ip;
    }
}

3. Registration center implementation

Realize registry management, add, delete, query

package register.list;

import com.alibaba.fastjson.JSONObject;
import common.RegisterTable;
import http.client.HttpClient;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.HashMap;

@Component
public class RegisterList {
    
    
    HashMap<String, ArrayList<RegisterTable>> hashMap = new HashMap<>();

    public JSONObject add(String name, String ip) {
    
    
        ArrayList<RegisterTable> list = hashMap.get(name);
        if (list == null) {
    
    
            list = new ArrayList<RegisterTable>();
        } else {
    
    
            for (RegisterTable table : list) {
    
    
                if (table.getIp().equals(ip)) {
    
    
                    return HttpClient.getResult(false, "repeat");
                }
            }
        }
        RegisterTable registerTable = new RegisterTable(name,ip);
        list.add(registerTable);
        hashMap.put(name, list);
        return HttpClient.getResult(true, "success");
    }

    public HashMap<String, ArrayList<RegisterTable>> getAll() {
    
    
        return hashMap;
    }

    public ArrayList<RegisterTable> getByName(String name) {
    
    
        return hashMap.get(name);
    }
}

Provide registration interface:

package register.control;

import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import register.list.RegisterList;

@RestController
@RequestMapping("/register")
public class Register {
    
    

    @Autowired
    RegisterList registerList;

    @PostMapping("/register")
    public JSONObject register(@RequestBody JSONObject data) {
    
    
        //处理注册逻辑
        return registerList.add(data.getString("name"), data.getString("ip"));
    }

    @GetMapping("/list/{name}")
    public Object getList(@PathVariable(value = "name", required = true) String name) {
    
    
        //获取注册列表
        return registerList.getByName(name);
    }

    @GetMapping("/list/all")
    public Object getList() {
    
    
        return registerList.getAll();
    }
}

4. provider module

Function: Send registration information to the registration center module after the project is started.

package common.register;

import com.alibaba.fastjson.JSONObject;
import http.client.HttpClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

@Component
public class Register implements ApplicationRunner {
    
    

    @Value("${model.name}")
    String name;

    @Value("${model.host}")
    String host;

    @Value("${model.port}")
    String port;

    @Value("${register.url}")
    String url;

    //发送注册消息
    @Override
    public void run(ApplicationArguments args) throws Exception {
    
    
        register();
    }

    private void register() throws Exception {
    
    
        JSONObject data = new JSONObject() {
    
    {
    
    
            put("name", name);
            put("ip", "http://" + host + ":" + port);
        }};
        HttpClient client = new HttpClient(url, null, null, data);
        client.httpPost();
    }
}

application.yml

server:
  port: 8001

model:
  name: "provider"
  port: "8001"
  host: "127.0.0.1"

register:
  url: "http://localhost:8080/register/register"

The other provider is the same, but the port is different.

5. Test

After startup:
Insert image description here
Query the registry: both modules have been registered.
Insert image description here

shortcoming

This approach has a very big disadvantage, that is, if you start the client first and then the server, the registration cannot be completed and an error message will be reported that the connection to the server failed. Therefore, the client needs to continuously re-register until successful.

Guess you like

Origin blog.csdn.net/weixin_42774617/article/details/131774416