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.
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:
Query the registry: both modules have been registered.
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.