[Technische Anwendung] Java stellt eine Verbindung zu Redis basierend auf dem UNIX-Domänen-Socket-Unix-Domänen-Socket her
-
- I. Einleitung
- 2. Springboot verfügt über einen integrierten Tomcat
- 3. Analyse der Unterstützung von Tomcat für das Unix-Domain-Socket-Protokoll
- 4. Der in Springboot integrierte Tomcat verwendet ein Beispiel für das Unixdomainsocket-Protokoll
- 5. Springboot External Tomcat konfiguriert den Unixdomainsocket
- 6. Zusammenfassung
I. Einleitung
In letzter Zeit wurden viele unix domain socket
in Arbeit befindliche **UNIX Domain Socket Protocol ()**-Anwendungen zusammengefasst, aber es gibt ein UNIX DOMAIN SOCKET协议
Anwendungsbeispiel, das von den am häufigsten verwendeten Komponenten in Arbeit unterstützt wird und nicht zusammengefasst wurde, nämlich: Tomcat unterstützt UNIX Domain-Sockets Anwendungsbeispiele für das Word-Protokoll (Unix-Domain-Socket) , heute zusammengefasst;
Beispiele früherer Anwendungen des UNIX-Domain-Socket-Protokolls in Komponenten:
2. Springboot verfügt über einen integrierten Tomcat
1. Springboot unterstützt die integrierte Funktion von Tomcat. Das Projekt kann zur Ausführung direkt in ein JAR-Paket kompiliert werden, und Tomcat kann in das Innere des JAR kompiliert werden, was die Anwendung vereinfacht. Dies ist auch eine wichtige Funktion von Springboot ;
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
2. Die Konfigurationselementattribute des in Springboot integrierten Tomcat werden normalerweise application.yml配置文件
wie folgt festgelegt:
server:
tomcat:
accept-count: 80 #挂起的请求队列最大连接数,默认100
max-connections: 2000 #最大连接数,默认10000,tomcat内tcp连接池的大小
max-threads: 200 #最大线程数,默认200,超过加入等待队列,默认是100,当等待队列达到100后,直接拒绝此次请求返回connection refused。连接超时时间默认为20秒
min-spare-threads: 5 #最小工作线程数
connection-timeout: 60000 #server端的socket超时间,默认60s
accesslog:
enabled: true #启动tomcat访问日志
Nach der Analyse aller Konfigurationselemente unixdomainsocket
wurden jedoch keine relevanten Konfigurationsinformationen gefunden, sodass apllication.yml配置文件
die Funktion unixdomainsocket nicht implementiert werden kann.
3. Konfigurieren Sie das integrierte Tocmat-Attribut über den Code in Springboot.
1) Konfigurieren Sie den Port des Servlet-Containers auf 9000
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import
org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
import org.springframework.stereotype.Component;
@Component
public class MyWebServerFactoryCustomizer implements
WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> {
@Override
public void customize(ConfigurableServletWebServerFactory server) {
server.setPort(9000);
}
}
2) Verwenden Sie ConfigurableServletWebServerFactory
Unterklassen (z. B. TomcatServletWebServerFactory
), um den Servlet-Container zu konfigurieren
import java.time.Duration;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.stereotype.Component;
@Component
public class MyTomcatWebServerFactoryCustomizer implements
WebServerFactoryCustomizer<TomcatServletWebServerFactory> {
@Override
public void customize(TomcatServletWebServerFactory server) {
server.addConnectorCustomizers((connector) ->
connector.setAsyncTimeout(Duration.ofSeconds(20).toMillis()));
}
}
3. Analyse der Unterstützung von Tomcat für das Unix-Domain-Socket-Protokoll
1. Die Zusammensetzung von Tomcat kann in zwei Teile unterteilt werden: 连接器
und 容器
Connector : Wird speziell zur Behandlung von Problemen im Zusammenhang mit Netzwerkverbindungen verwendet, z. B. Socket-Links in der Webentwicklung, Anforderungskapselung, Verbindungs-Thread-Pools usw.
Container (Servlet) : Wird zum Speichern der von uns geschriebenen Website-Programme verwendet. Tomcat verfügt insgesamt über vier Container: Engine, Host, Context und Wrapper. Ein Wrapper entspricht einem Servlet, ein Kontext entspricht einer Anwendung (standardmäßig entspricht die in webapps/ROOT gespeicherte Hauptanwendung beispielsweise dem Stammverzeichnis einer Site), ein Host entspricht einer Site (z. B. einer anderen Domäne). Namen) und Engine ist die Engine .
2. Die für die Verarbeitung von Anforderungen im Connector verantwortlichen Protokolle basieren hauptsächlich auf bio,nio,nio2,apr
mehreren verschiedenen http-Protokollen, und 支持NIO协议
die Attributeinstellungen unterstützen die unixdomainsocket属性
Konfiguration.
pollerThreadPriority:(int)The priority of the poller threads
selectorTimeout:(int)The time in milliseconds to timeout on a select() for the poller
useSendfile:(bool)Use this attribute to enable or disable sendfile capability
socket.directBuffer:(bool)Boolean value, whether to use direct ByteBuffers or java mapped ByteBuffers
socket.directSslBuffer:(bool)Boolean value, whether to use direct ByteBuffers or java mapped ByteBuffers for the SSL buffers
socket.appReadBufSize:(int)Each connection that is opened up in Tomcat get associated with a read ByteBuffer
socket.appWriteBufSize:(int)Each connection that is opened up in Tomcat get associated with a write ByteBuffer
socket.bufferPool:(int)The NIOx connector uses a class called NioXChannel that holds elements linked to a socket
socket.bufferPoolSize:(int)The NioXChannel pool can also be size based, not used object based
socket.processorCache:(int)Tomcat will cache SocketProcessor objects to reduce garbage collection
socket.eventCache:(int)Tomcat will cache PollerEvent objects to reduce garbage collection
unixDomainSocketPath:Where supported, the path to a Unix Domain Socket that this Connector will create and await incoming connections
unixDomainSocketPathPermissions:Where supported, the posix permissions that will be applied to the to the Unix Domain Socket specified with unixDomainSocketPath above
useInheritedChannel:(bool)Defines if this connector should inherit an inetd/systemd network socket
Daher müssen wir nur das Attribut unixDomainSocketPath festlegen.
4. Der in Springboot integrierte Tomcat verwendet ein Beispiel für das Unixdomainsocket-Protokoll
1. JDK-Version
Bei Verwendung des integrierten Tomcat von Springboot wird das abhängige JDK verwendet 最低版本是jdk16
, da Unix-Sockets erst ab jdk16 unterstützt werden.
Im Jahr 2019 bieten Windows Server und Windows 10 Unterstützung für Unix-Sockets und Unix-Sockets werden häufig verwendet Kommunikation zwischen lokalen Prozessen. Im Vergleich zum TCP-Protokoll können lokale Prozesse mithilfe von Unix-Sockets effizienter und sicherer kommunizieren. JDK16 fügt eine neue Schnittstelle für Unix-Sockets hinzu java.net.UnixDomainSocketAddress
, um diese Funktion zu unterstützen
Wenn die JDK-Version niedriger als 16 ist, wird ein Fehler gemeldet:
Caused by: java.lang.UnsupportedOperationException: Java Runtime does not support Unix domain sockets. You must use Java 16 to use this feature.
at org.apache.tomcat.util.compat.JreCompat.openUnixDomainServerSocketChannel(JreCompat.java:337) ~[tomcat-embed-core-9.0.70.jar:9.0.70]
at org.apache.tomcat.util.net.NioEndpoint.initServerSocket(NioEndpoint.java:252) ~[tomcat-embed-core-9.0.70.jar:9.0.70]
at org.apache.tomcat.util.net.NioEndpoint.bind(NioEndpoint.java:230) ~[tomcat-embed-core-9.0.70.jar:9.0.70]
at org.apache.tomcat.util.net.AbstractEndpoint.bindWithCleanup(AbstractEndpoint.java:1227) ~[tomcat-embed-core-9.0.70.jar:9.0.70]
at org.apache.tomcat.util.net.AbstractEndpoint.init(AbstractEndpoint.java:1240) ~[tomcat-embed-core-9.0.70.jar:9.0.70]
at org.apache.coyote.AbstractProtocol.init(AbstractProtocol.java:604) ~[tomcat-embed-core-9.0.70.jar:9.0.70]
at org.apache.coyote.http11.AbstractHttp11Protocol.init(AbstractHttp11Protocol.java:76) ~[tomcat-embed-core-9.0.70.jar:9.0.70]
at org.apache.catalina.connector.Connector.initInternal(Connector.java:1047) ~[tomcat-embed-core-9.0.70.jar:9.0.70]
... 21 common frames omitted
Also verwenden wir jdk19
<properties>
<java.version>19</java.version>
</properties>
2. Springboot-integrierte Tomcat-Attributkonfiguration
Mit dem integrierten Tomcat von Springboot lässt sich das Unix-Domain-Socket-Protokoll sehr einfach konfigurieren. Sie müssen es nur festlegenconnector.setProperty("unixDomainSocketPath","D:\\http.sock")
package com.example.tomcat19.config;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MyTomcatWebServerFactoryCustomizer implements WebServerFactoryCustomizer<TomcatServletWebServerFactory> {
@Override
public void customize(TomcatServletWebServerFactory server) {
server.addConnectorCustomizers((connector) -> {
//connector.setAsyncTimeout(Duration.ofSeconds(20).toMillis());
//connector.setProperty("protocol","org.apache.coyote.http11.Http11NioProtocol");
connector.setProperty("unixDomainSocketPath","D:\\http.sock");
}
);
}
}
3. Serverseitige Testschnittstelle
package com.example.tomcat19.action;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@Slf4j
@RestController
public class TestAction {
@GetMapping("/test")
public String test(){
log.info("收到请求id:1");
return "哈哈哈";
}
}
Struktur des Serverprojekts:
4. Kunden anfordern
Um die Überprüfung zu erleichtern, verwenden wir hier socket
das http.sock
Senden von HTTP-Anforderungsnachrichten an den Server.
package com.sk.init;
import java.net.StandardProtocolFamily;
import java.net.UnixDomainSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
public class Test {
public static void main(String[] args) throws Exception{
// 建立 Unix Socket 连接
//File sockFile = new File("D:\\http.sock");
SocketChannel socketChannel = SocketChannel.open(StandardProtocolFamily.UNIX);
UnixDomainSocketAddress of = UnixDomainSocketAddress.of("D:\\http.sock");
//UnixDomainSocketAddress of = UnixDomainSocketAddress.of("D:\\test.sock");
boolean connect = socketChannel.connect(of);
System.out.println(connect);
String newData = "this is domain socket..." + System.currentTimeMillis();
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append("GET /test HTTP/1.1").append("\n");
stringBuffer.append("Host: 127.0.0.1").append("\r\n");
stringBuffer.append("Connection: keep-alive").append("\r\n");
stringBuffer.append("Cache-Control: max-age=0").append("\r\n");
stringBuffer.append("sec-ch-ua: \" Not A;Brand\";v=\"99\", \"Chromium\";v=\"100\", \"Google Chrome\";v=\"100\"").append("\r\n");
stringBuffer.append("sec-ch-ua-mobile: ?0").append("\r\n");
stringBuffer.append("sec-ch-ua-platform: \"Windows\"").append("\r\n");
stringBuffer.append("Upgrade-Insecure-Requests: 1").append("\r\n");
stringBuffer.append("User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.75 Safari/537.36").append("\r\n");
stringBuffer.append("Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9").append("\r\n");
stringBuffer.append("Sec-Fetch-Site: none").append("\r\n");
stringBuffer.append("Sec-Fetch-Mode: navigate").append("\r\n");
stringBuffer.append("Sec-Fetch-User: ?1").append("\r\n");
stringBuffer.append("Sec-Fetch-Dest: document").append("\r\n");
stringBuffer.append("Accept-Encoding: gzip, deflate, br").append("\r\n");
stringBuffer.append("Accept-Language: zh-CN,zh;q=0.9").append("\r\n");
stringBuffer.append("\r\n");
//stringBuffer.append("Accept: */*").append("\r\n");
ByteBuffer buf = ByteBuffer.allocate(2048);
buf.clear();
buf.put(stringBuffer.toString().getBytes());
//buf.put(newData.getBytes());
buf.flip();
while (buf.hasRemaining()) {
socketChannel.write(buf);
}
socketChannel.close();
}
}
5. Fordern Sie Ergebnisse an
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v3.0.2-SNAPSHOT)
23:06:54.720 [main] INFO org.springframework.boot.StartupInfoLogger.logStarting(StartupInfoLogger.java:51) - Starting Tomcat19Application using Java 19.0.1 with PID 6248 (G:\work3\UDS redis\tomcat19\target\classes started by Administrator in G:\work3\UDS redis\tomcat19)
23:06:54.962 [main] INFO org.springframework.boot.SpringApplication.logStartupProfileInfo(SpringApplication.java:630) - No active profile set, falling back to 1 default profile: "default"
23:06:55.895 [main] INFO org.springframework.boot.web.embedded.tomcat.TomcatWebServer.initialize(TomcatWebServer.java:108) - Tomcat initialized with port(s): 8086 (http)
23:06:55.905 [main] INFO org.apache.juli.logging.DirectJDKLog.log(DirectJDKLog.java:173) - Initializing ProtocolHandler ["http-nio-D:\\http.sock"]
23:06:55.906 [main] INFO org.apache.juli.logging.DirectJDKLog.log(DirectJDKLog.java:173) - Starting service [Tomcat]
23:06:55.906 [main] INFO org.apache.juli.logging.DirectJDKLog.log(DirectJDKLog.java:173) - Starting Servlet engine: [Apache Tomcat/10.1.4]
23:06:55.996 [main] INFO org.apache.juli.logging.DirectJDKLog.log(DirectJDKLog.java:173) - Initializing Spring embedded WebApplicationContext
23:06:55.996 [main] INFO org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.prepareWebApplicationContext(ServletWebServerApplicationContext.java:291) - Root WebApplicationContext: initialization completed in 991 ms
23:06:56.344 [main] INFO org.apache.juli.logging.DirectJDKLog.log(DirectJDKLog.java:173) - Starting ProtocolHandler ["http-nio-D:\\http.sock"]
23:06:56.364 [main] INFO org.springframework.boot.web.embedded.tomcat.TomcatWebServer.start(TomcatWebServer.java:220) - Tomcat started on port(s): -1 (http) with context path ''
23:06:56.374 [main] INFO org.springframework.boot.StartupInfoLogger.logStarted(StartupInfoLogger.java:57) - Started Tomcat19Application in 2.287 seconds (process running for 4.057)
23:07:12.012 [http-nio-D:\\http.sock-exec-1] INFO org.apache.juli.logging.DirectJDKLog.log(DirectJDKLog.java:173) - Initializing Spring DispatcherServlet 'dispatcherServlet'
23:07:12.032 [http-nio-D:\\http.sock-exec-1] INFO org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:532) - Initializing Servlet 'dispatcherServlet'
23:07:12.033 [http-nio-D:\\http.sock-exec-1] INFO org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:554) - Completed initialization in 1 ms
23:07:12.062 [http-nio-D:\\http.sock-exec-1] INFO com.example.tomcat19.action.TestAction.test(TestAction.java:13) - 收到请求id:1
5. Springboot External Tomcat konfiguriert den Unixdomainsocket
<Service name="CatalinaLocal">
<Connector
protocol="org.apache.coyote.http11.Http11AprProtocol"
unixDomainSocketPath="/opt/app-name/http.sock" />
<Engine
defaultHost="localhost"
name="Catalina">
<Host
name="localhost"
appBase="webapps"
unpackWARs="true"
autoDeploy="false"
deployIgnore="(?!.*hawtio).*">
<Valve
className="org.apache.catalina.valves.RemoteIpValve" />
</Host>
</Engine>
</Service>
Hinweis: Die Konfiguration hier wurde nicht überprüft. Wenn Sie interessiert sind, können Sie sie in der Praxis testen.
6. Zusammenfassung
unix域套接字协议
Es ist immer noch sehr nützlich, insbesondere wenn es um die Leistungsoptimierung geht. Die Microservice-Architekturen vieler großer Hersteller unterstützen das Unix Domain Socket Protocol;
=Wenn der Artikel für Sie hilfreich ist, liken Sie ihn bitte und sammeln Sie ihn=====================