This is an automated email from the ASF dual-hosted git repository.
xiaoyu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-shenyu.git
The following commit(s) were added to refs/heads/master by this push:
new 09c571cbc Features: new shenyu-proxy, partial implementation of the
network layer. (#3074)
09c571cbc is described below
commit 09c571cbc2df0fa9449c23756b2e117cf7e6543f
Author: Sixh-PrFor <[email protected]>
AuthorDate: Mon Apr 18 14:03:07 2022 +0800
Features: new shenyu-proxy, partial implementation of the network layer.
(#3074)
* New shenyu-proxy, partial implementation of the network layer.
* New shenyu-proxy, partial implementation of the network layer.
* New shenyu-proxy, partial implementation of the network layer.
* fix: pls in english
* fix: pls in english
* channel business encapsulation
---
pom.xml | 1 +
.../loadbalancer/cache/UpstreamCheckTaskTest.java | 2 +-
shenyu-proxy/pom.xml | 47 +++++++
shenyu-proxy/proxy-remote/pom.xml | 41 ++++++
.../apache/shenyu/proxy/remote/AbstractServer.java | 109 +++++++++++++++
.../org/apache/shenyu/proxy/remote/Channel.java | 76 +++++++++++
.../apache/shenyu/proxy/remote/ChannelFuture.java | 55 ++++++++
.../apache/shenyu/proxy/remote/ChannelHandler.java | 63 +++++++++
.../org/apache/shenyu/proxy/remote/Server.java | 31 +++++
.../apache/shenyu/proxy/remote/ServerConfig.java | 70 ++++++++++
.../shenyu/proxy/remote/netty/NettyChannel.java | 150 +++++++++++++++++++++
.../proxy/remote/netty/NettyChannelFuture.java | 80 +++++++++++
.../shenyu/proxy/remote/netty/NettyServer.java | 136 +++++++++++++++++++
.../proxy/remote/netty/NettyServerHandler.java | 114 ++++++++++++++++
.../shenyu/proxy/remote/NettyServerTest.java | 33 +++++
15 files changed, 1007 insertions(+), 1 deletion(-)
diff --git a/pom.xml b/pom.xml
index b7e276887..7c99cc567 100644
--- a/pom.xml
+++ b/pom.xml
@@ -42,6 +42,7 @@
<module>shenyu-protocol</module>
<module>shenyu-loadbalancer</module>
<module>shenyu-dist</module>
+ <module>shenyu-proxy</module>
</modules>
<licenses>
diff --git
a/shenyu-loadbalancer/src/test/java/org/apache/shenyu/loadbalancer/cache/UpstreamCheckTaskTest.java
b/shenyu-loadbalancer/src/test/java/org/apache/shenyu/loadbalancer/cache/UpstreamCheckTaskTest.java
index 5dbb5db52..51c0a21cd 100644
---
a/shenyu-loadbalancer/src/test/java/org/apache/shenyu/loadbalancer/cache/UpstreamCheckTaskTest.java
+++
b/shenyu-loadbalancer/src/test/java/org/apache/shenyu/loadbalancer/cache/UpstreamCheckTaskTest.java
@@ -84,7 +84,7 @@ public class UpstreamCheckTaskTest {
// Let it coverage line 151~163.
when(upstream.isHealthy()).thenReturn(false).thenReturn(true);
// Even if the address could not connect, it will return false, that
mean it will not coverage 151~163.
- when(upstream.getUrl()).thenReturn("http://www.baidu.com");
+ when(upstream.getUrl()).thenReturn("https://www.baidu.com");
// Manually run one time
healthCheckTask.run();
Awaitility.await().pollDelay(1, TimeUnit.SECONDS).untilAsserted(() ->
assertFalse(healthCheckTask.getCheckStarted().get()));
diff --git a/shenyu-proxy/pom.xml b/shenyu-proxy/pom.xml
new file mode 100644
index 000000000..accee5c8f
--- /dev/null
+++ b/shenyu-proxy/pom.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one or more
+ ~ contributor license agreements. See the NOTICE file distributed with
+ ~ this work for additional information regarding copyright ownership.
+ ~ The ASF licenses this file to You under the Apache License, Version 2.0
+ ~ (the "License"); you may not use this file except in compliance with
+ ~ the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<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">
+ <parent>
+ <artifactId>shenyu</artifactId>
+ <groupId>org.apache.shenyu</groupId>
+ <version>2.4.3-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>shenyu-proxy</artifactId>
+ <packaging>pom</packaging>
+ <modules>
+ <module>proxy-remote</module>
+ </modules>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.shenyu</groupId>
+ <artifactId>shenyu-common</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ </dependencies>
+
+ <properties>
+ <maven.compiler.source>8</maven.compiler.source>
+ <maven.compiler.target>8</maven.compiler.target>
+ </properties>
+
+</project>
\ No newline at end of file
diff --git a/shenyu-proxy/proxy-remote/pom.xml
b/shenyu-proxy/proxy-remote/pom.xml
new file mode 100644
index 000000000..b92a8118b
--- /dev/null
+++ b/shenyu-proxy/proxy-remote/pom.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one or more
+ ~ contributor license agreements. See the NOTICE file distributed with
+ ~ this work for additional information regarding copyright ownership.
+ ~ The ASF licenses this file to You under the Apache License, Version 2.0
+ ~ (the "License"); you may not use this file except in compliance with
+ ~ the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<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">
+ <parent>
+ <artifactId>shenyu-proxy</artifactId>
+ <groupId>org.apache.shenyu</groupId>
+ <version>2.4.3-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>proxy-remote</artifactId>
+ <dependencies>
+ <dependency>
+ <groupId>io.netty</groupId>
+ <artifactId>netty-all</artifactId>
+ </dependency>
+ </dependencies>
+ <properties>
+ <maven.compiler.source>8</maven.compiler.source>
+ <maven.compiler.target>8</maven.compiler.target>
+ </properties>
+
+</project>
\ No newline at end of file
diff --git
a/shenyu-proxy/proxy-remote/src/main/java/org/apache/shenyu/proxy/remote/AbstractServer.java
b/shenyu-proxy/proxy-remote/src/main/java/org/apache/shenyu/proxy/remote/AbstractServer.java
new file mode 100644
index 000000000..d2c905159
--- /dev/null
+++
b/shenyu-proxy/proxy-remote/src/main/java/org/apache/shenyu/proxy/remote/AbstractServer.java
@@ -0,0 +1,109 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shenyu.proxy.remote;
+
+/**
+ * AbstractServer .
+ * start server abstraction.
+ */
+public abstract class AbstractServer implements Server, ChannelHandler {
+
+ /**
+ * Handle related handlers.
+ */
+ private final ChannelHandler channelHandler;
+
+ /**
+ * Instantiates a new Abstract server.
+ *
+ * @param channelHandler the channel handler
+ */
+ public AbstractServer(final ChannelHandler channelHandler) {
+ this.channelHandler = channelHandler;
+ }
+
+ /**
+ * start a server.
+ *
+ * @param config Started config processing.
+ */
+ @Override
+ public void start(final ServerConfig config) {
+ this.start0(config.getPort());
+ }
+
+ /**
+ * send a message.
+ *
+ * @param channel the channel
+ * @param message the message
+ */
+ @Override
+ public void sent(final Channel channel, final Object message) {
+ channelHandler.sent(channel, message);
+ }
+
+ /**
+ * Handling of received messages.
+ *
+ * @param channel the channel
+ * @param message the message
+ */
+ @Override
+ public void receive(final Channel channel, final Object message) {
+ channelHandler.receive(channel, message);
+ }
+
+ /**
+ * connect.
+ *
+ * @param channel the channel
+ */
+ @Override
+ public void connection(final Channel channel) {
+ channelHandler.connection(channel);
+ }
+
+ /**
+ * Disconnect.
+ *
+ * @param channel the channel
+ */
+ @Override
+ public void disConnection(final Channel channel) {
+ channelHandler.disConnection(channel);
+ }
+
+ /**
+ * An exception occurred.
+ *
+ * @param channel the channel
+ * @param throwable the throwable
+ */
+ @Override
+ public void caught(final Channel channel, final Throwable throwable) {
+ channelHandler.caught(channel, throwable);
+ }
+
+ /**
+ * start a server.
+ *
+ * @param port the port
+ */
+ protected abstract void start0(int port);
+}
diff --git
a/shenyu-proxy/proxy-remote/src/main/java/org/apache/shenyu/proxy/remote/Channel.java
b/shenyu-proxy/proxy-remote/src/main/java/org/apache/shenyu/proxy/remote/Channel.java
new file mode 100644
index 000000000..4ed21d346
--- /dev/null
+++
b/shenyu-proxy/proxy-remote/src/main/java/org/apache/shenyu/proxy/remote/Channel.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shenyu.proxy.remote;
+
+import java.net.SocketAddress;
+
+/**
+ * Channel .
+ * Encapsulate the channel.
+ */
+public interface Channel {
+
+ /**
+ * send.
+ * Send data to network channel.
+ *
+ * @param message the message
+ * @return the channel future
+ */
+ ChannelFuture send(Object message);
+
+ /**
+ * Determine if it is connected.
+ *
+ * @return boolean boolean
+ */
+ boolean isConnected();
+
+ /**
+ * remote address.
+ *
+ * @return socket address
+ */
+ SocketAddress remoteAddress();
+
+ /**
+ * Local address socket address.
+ *
+ * @return the socket address
+ */
+ SocketAddress localAddress();
+
+ /**
+ * Is opened boolean.
+ *
+ * @return the boolean
+ */
+ boolean isOpened();
+
+ /**
+ * Is close boolean.
+ *
+ * @return the boolean
+ */
+ boolean isClose();
+
+ /**
+ * Close.
+ */
+ void close();
+}
diff --git
a/shenyu-proxy/proxy-remote/src/main/java/org/apache/shenyu/proxy/remote/ChannelFuture.java
b/shenyu-proxy/proxy-remote/src/main/java/org/apache/shenyu/proxy/remote/ChannelFuture.java
new file mode 100644
index 000000000..6b9644d8d
--- /dev/null
+++
b/shenyu-proxy/proxy-remote/src/main/java/org/apache/shenyu/proxy/remote/ChannelFuture.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shenyu.proxy.remote;
+
+import java.util.function.Consumer;
+
+/**
+ * ChannelFuture .
+ * channel future.
+ */
+public interface ChannelFuture {
+
+ /**
+ * Complete.
+ *
+ * @param consumer the consumer
+ */
+ void onComplete(Consumer<ChannelFuture> consumer);
+
+ /**
+ * Is done boolean.
+ *
+ * @return the boolean
+ */
+ boolean isDone();
+
+ /**
+ * Cause thread.
+ *
+ * @return the thread
+ */
+ Throwable cause();
+
+ /**
+ * Is connected boolean.
+ *
+ * @return the boolean
+ */
+ boolean isConnected();
+}
diff --git
a/shenyu-proxy/proxy-remote/src/main/java/org/apache/shenyu/proxy/remote/ChannelHandler.java
b/shenyu-proxy/proxy-remote/src/main/java/org/apache/shenyu/proxy/remote/ChannelHandler.java
new file mode 100644
index 000000000..fc467d0ec
--- /dev/null
+++
b/shenyu-proxy/proxy-remote/src/main/java/org/apache/shenyu/proxy/remote/ChannelHandler.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shenyu.proxy.remote;
+
+/**
+ * ChannelHandler .
+ * channel handler Processed event notifications.
+ */
+public interface ChannelHandler {
+
+ /**
+ * send a message.
+ *
+ * @param channel the channel
+ * @param message the message
+ */
+ void sent(Channel channel, Object message);
+
+ /**
+ * Handling of received messages.
+ *
+ * @param channel the channel
+ * @param message the message
+ */
+ void receive(Channel channel, Object message);
+
+ /**
+ * connect.
+ *
+ * @param channel the channel
+ */
+ void connection(Channel channel);
+
+ /**
+ * Disconnect.
+ *
+ * @param channel the channel
+ */
+ void disConnection(Channel channel);
+
+ /**
+ * An exception occurred.
+ *
+ * @param channel the channel
+ * @param throwable the throwable
+ */
+ void caught(Channel channel, Throwable throwable);
+}
diff --git
a/shenyu-proxy/proxy-remote/src/main/java/org/apache/shenyu/proxy/remote/Server.java
b/shenyu-proxy/proxy-remote/src/main/java/org/apache/shenyu/proxy/remote/Server.java
new file mode 100644
index 000000000..973d3e95f
--- /dev/null
+++
b/shenyu-proxy/proxy-remote/src/main/java/org/apache/shenyu/proxy/remote/Server.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shenyu.proxy.remote;
+
+/**
+ * Server .
+ */
+public interface Server extends ChannelHandler {
+
+ /**
+ * start server.
+ *
+ * @param config config.
+ */
+ void start(ServerConfig config);
+}
diff --git
a/shenyu-proxy/proxy-remote/src/main/java/org/apache/shenyu/proxy/remote/ServerConfig.java
b/shenyu-proxy/proxy-remote/src/main/java/org/apache/shenyu/proxy/remote/ServerConfig.java
new file mode 100644
index 000000000..45c297a56
--- /dev/null
+++
b/shenyu-proxy/proxy-remote/src/main/java/org/apache/shenyu/proxy/remote/ServerConfig.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shenyu.proxy.remote;
+
+/**
+ * ServerConfig .
+ */
+public class ServerConfig {
+
+ /**
+ * address.
+ */
+ private String address;
+
+ /**
+ * port.
+ */
+ private Integer port;
+
+ /**
+ * Gets address.
+ *
+ * @return the address
+ */
+ public String getAddress() {
+ return address;
+ }
+
+ /**
+ * Sets address.
+ *
+ * @param address the address
+ */
+ public void setAddress(final String address) {
+ this.address = address;
+ }
+
+ /**
+ * Gets port.
+ *
+ * @return the port
+ */
+ public Integer getPort() {
+ return port;
+ }
+
+ /**
+ * Sets port.
+ *
+ * @param port the port
+ */
+ public void setPort(final Integer port) {
+ this.port = port;
+ }
+}
diff --git
a/shenyu-proxy/proxy-remote/src/main/java/org/apache/shenyu/proxy/remote/netty/NettyChannel.java
b/shenyu-proxy/proxy-remote/src/main/java/org/apache/shenyu/proxy/remote/netty/NettyChannel.java
new file mode 100644
index 000000000..0915d27b4
--- /dev/null
+++
b/shenyu-proxy/proxy-remote/src/main/java/org/apache/shenyu/proxy/remote/netty/NettyChannel.java
@@ -0,0 +1,150 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shenyu.proxy.remote.netty;
+
+import io.netty.channel.ChannelFutureListener;
+import org.apache.shenyu.proxy.remote.Channel;
+import org.apache.shenyu.proxy.remote.ChannelFuture;
+
+import java.net.SocketAddress;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+/**
+ * NettyChannel .
+ */
+public class NettyChannel implements Channel {
+
+ private static final ConcurrentMap<io.netty.channel.Channel, NettyChannel>
CHANNEL_CACHE = new ConcurrentHashMap<>();
+
+ private final io.netty.channel.Channel channel;
+
+ /**
+ * Instantiates a new Netty channel.
+ *
+ * @param channel the channel
+ */
+ public NettyChannel(final io.netty.channel.Channel channel) {
+ this.channel = channel;
+ }
+
+ /**
+ * send.
+ * Send data to network channel.
+ *
+ * @param message the message
+ * @return the channel future
+ */
+ @Override
+ public ChannelFuture send(final Object message) {
+ io.netty.channel.ChannelFuture channelFuture =
channel.writeAndFlush(message);
+ return new NettyChannelFuture(channelFuture);
+ }
+
+ /**
+ * Determine if it is connected.
+ *
+ * @return boolean boolean
+ */
+ @Override
+ public boolean isConnected() {
+ return channel.isActive();
+ }
+
+ /**
+ * remote address.
+ *
+ * @return socket address
+ */
+ @Override
+ public SocketAddress remoteAddress() {
+ return channel.remoteAddress();
+ }
+
+ /**
+ * Local address socket address.
+ *
+ * @return the socket address
+ */
+ @Override
+ public SocketAddress localAddress() {
+ return channel.localAddress();
+ }
+
+ /**
+ * Is opened boolean.
+ *
+ * @return the boolean
+ */
+ @Override
+ public boolean isOpened() {
+ return channel.isOpen();
+ }
+
+ /**
+ * Is close boolean.
+ *
+ * @return the boolean
+ */
+ @Override
+ public boolean isClose() {
+ return !this.isOpened();
+ }
+
+ /**
+ * Close.
+ */
+ @Override
+ public void close() {
+ channel.close().addListener((ChannelFutureListener) channelFuture -> {
+ removeChannel(channel);
+ });
+ }
+
+ /**
+ * Get a channel, create a Netty Channel if it doesn't exist.
+ *
+ * @param channel the channel nettyChannel.
+ * @return the or add channel
+ */
+ public static NettyChannel getOrAddChannel(final io.netty.channel.Channel
channel) {
+ NettyChannel nettyChannel = CHANNEL_CACHE.get(channel);
+
+ if (nettyChannel == null) {
+ NettyChannel ret = new NettyChannel(channel);
+ if (channel.isActive()) {
+ nettyChannel = CHANNEL_CACHE.putIfAbsent(channel, ret);
+ }
+ if (nettyChannel == null) {
+ nettyChannel = ret;
+ }
+ }
+ return nettyChannel;
+ }
+
+ /**
+ * If the channel has been disconnected, it is removed from the cache.
+ *
+ * @param channel the channel
+ */
+ public static void removeChannel(final io.netty.channel.Channel channel) {
+ if (channel != null && !channel.isActive()) {
+ CHANNEL_CACHE.remove(channel);
+ }
+ }
+}
diff --git
a/shenyu-proxy/proxy-remote/src/main/java/org/apache/shenyu/proxy/remote/netty/NettyChannelFuture.java
b/shenyu-proxy/proxy-remote/src/main/java/org/apache/shenyu/proxy/remote/netty/NettyChannelFuture.java
new file mode 100644
index 000000000..92a0d5d54
--- /dev/null
+++
b/shenyu-proxy/proxy-remote/src/main/java/org/apache/shenyu/proxy/remote/netty/NettyChannelFuture.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shenyu.proxy.remote.netty;
+
+import org.apache.shenyu.proxy.remote.ChannelFuture;
+
+import java.util.function.Consumer;
+
+/**
+ * NettyChannelFuture .
+ * proxy wap channel future.
+ */
+public class NettyChannelFuture implements ChannelFuture {
+
+ private io.netty.channel.ChannelFuture future;
+
+ /**
+ * Instantiates a new Netty channel future..
+ *
+ * @param future future.
+ */
+ public NettyChannelFuture(final io.netty.channel.ChannelFuture future) {
+ this.future = future;
+ }
+
+ /**
+ * Complete.
+ *
+ * @param consumer the consumer
+ */
+ @Override
+ public void onComplete(final Consumer<ChannelFuture> consumer) {
+
+ }
+
+ /**
+ * Is done boolean.
+ *
+ * @return the boolean
+ */
+ @Override
+ public boolean isDone() {
+ return false;
+ }
+
+ /**
+ * Cause thread.
+ *
+ * @return the thread
+ */
+ @Override
+ public Throwable cause() {
+ return null;
+ }
+
+ /**
+ * Is connected boolean.
+ *
+ * @return the boolean
+ */
+ @Override
+ public boolean isConnected() {
+ return false;
+ }
+}
diff --git
a/shenyu-proxy/proxy-remote/src/main/java/org/apache/shenyu/proxy/remote/netty/NettyServer.java
b/shenyu-proxy/proxy-remote/src/main/java/org/apache/shenyu/proxy/remote/netty/NettyServer.java
new file mode 100644
index 000000000..ef48e3af6
--- /dev/null
+++
b/shenyu-proxy/proxy-remote/src/main/java/org/apache/shenyu/proxy/remote/netty/NettyServer.java
@@ -0,0 +1,136 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shenyu.proxy.remote.netty;
+
+import io.netty.bootstrap.ServerBootstrap;
+import io.netty.buffer.PooledByteBufAllocator;
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelInitializer;
+import io.netty.channel.ChannelOption;
+import io.netty.channel.EventLoopGroup;
+import io.netty.channel.epoll.EpollEventLoopGroup;
+import io.netty.channel.epoll.EpollServerSocketChannel;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.channel.socket.nio.NioServerSocketChannel;
+import io.netty.handler.codec.http.HttpObjectAggregator;
+import io.netty.handler.codec.http.HttpRequestDecoder;
+import io.netty.handler.codec.http.HttpResponseEncoder;
+import io.netty.handler.stream.ChunkedWriteHandler;
+import io.netty.handler.timeout.IdleStateHandler;
+import org.apache.shenyu.common.concurrent.ShenyuThreadFactory;
+import org.apache.shenyu.proxy.remote.AbstractServer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.net.InetSocketAddress;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * NettyServer .
+ * netty network management.
+ */
+public class NettyServer extends AbstractServer {
+
+ private final Logger logger = LoggerFactory.getLogger(NettyServer.class);
+
+ /**
+ * service starter.
+ */
+ private final ServerBootstrap server;
+
+ /**
+ * service processing.
+ */
+ private EventLoopGroup boosGroup;
+
+ /**
+ * task processing thread.
+ */
+ private EventLoopGroup workGroup;
+
+ private final int threads = Runtime.getRuntime().availableProcessors() <<
1;
+
+
+ /**
+ * Instantiates a new Abstract server.
+ */
+ public NettyServer() {
+ super(null);
+ this.server = new ServerBootstrap();
+ }
+
+ /**
+ * start a server.
+ *
+ * @param port the port
+ */
+ @Override
+ protected void start0(final int port) {
+ //Judge Linux system
+ if (isLinux()) {
+ boosGroup = new EpollEventLoopGroup(1,
ShenyuThreadFactory.create("shenyu_proxy_server_boss_epoll", false));
+ workGroup = new EpollEventLoopGroup(threads,
ShenyuThreadFactory.create("shenyu_proxy_server_work_epoll", false));
+ server.channel(EpollServerSocketChannel.class);
+ } else {
+ boosGroup = new NioEventLoopGroup(1,
ShenyuThreadFactory.create("shenyu_proxy_server_boss_epoll", false));
+ workGroup = new NioEventLoopGroup(threads,
ShenyuThreadFactory.create("shenyu_proxy_server_work_epoll", false));
+ server.channel(NioServerSocketChannel.class);
+ }
+ NettyServerHandler nettyServerHandler = new NettyServerHandler(this);
+ server.group(boosGroup, workGroup)
+ .option(ChannelOption.SO_BACKLOG, 65535)
+ .option(ChannelOption.SO_REUSEADDR, true)
+ .option(ChannelOption.SO_KEEPALIVE, true)
+ .option(ChannelOption.ALLOCATOR,
PooledByteBufAllocator.DEFAULT)
+ .childOption(ChannelOption.TCP_NODELAY, true)
+ .childOption(ChannelOption.ALLOCATOR,
PooledByteBufAllocator.DEFAULT)
+ .childHandler(new ChannelInitializer<Channel>() {
+ @Override
+ protected void initChannel(final Channel channel) {
+ channel.pipeline().addLast(new IdleStateHandler(4000,
0, 0, TimeUnit.MILLISECONDS));
+ channel.pipeline().addLast("http-decoder", new
HttpRequestDecoder());
+ channel.pipeline().addLast("http-aggregator", new
HttpObjectAggregator(65535));
+ channel.pipeline().addLast("http-encoder", new
HttpResponseEncoder());
+ channel.pipeline().addLast("chunkedWriter", new
ChunkedWriteHandler());
+ channel.pipeline().addLast(nettyServerHandler);
+ }
+ });
+ //setup information
+ try {
+ Channel channel = server.bind(port).sync().channel();
+ logger.info("Network listening,ip:{},port:{}",
((InetSocketAddress) channel.localAddress()).getHostString(), port);
+ channel.closeFuture().sync();
+ } catch (InterruptedException e) {
+ logger.error("Error Network listening...... " + e.getMessage());
+ throw new RuntimeException("Error Network listening " +
e.getMessage());
+ } finally {
+ boosGroup.shutdownGracefully();
+ workGroup.shutdownGracefully();
+ }
+ }
+
+ /**
+ * Determine whether it is a Linux operating system.
+ *
+ * @return the boolean
+ */
+ public static boolean isLinux() {
+ final String oS = System.getProperty("os.name").toLowerCase();
+ return oS.contains("linux");
+ }
+}
diff --git
a/shenyu-proxy/proxy-remote/src/main/java/org/apache/shenyu/proxy/remote/netty/NettyServerHandler.java
b/shenyu-proxy/proxy-remote/src/main/java/org/apache/shenyu/proxy/remote/netty/NettyServerHandler.java
new file mode 100644
index 000000000..0a8a1b550
--- /dev/null
+++
b/shenyu-proxy/proxy-remote/src/main/java/org/apache/shenyu/proxy/remote/netty/NettyServerHandler.java
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shenyu.proxy.remote.netty;
+
+import io.netty.channel.ChannelDuplexHandler;
+import io.netty.channel.ChannelHandler;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelPromise;
+import io.netty.handler.timeout.IdleState;
+import io.netty.handler.timeout.IdleStateEvent;
+
+/**
+ * NettyServerHandler .
+ * Processing of netty server.
+ *
+ * @author sixh chenbin
+ */
[email protected]
+public class NettyServerHandler extends ChannelDuplexHandler {
+
+ private final org.apache.shenyu.proxy.remote.ChannelHandler channelHandler;
+
+ public NettyServerHandler(final
org.apache.shenyu.proxy.remote.ChannelHandler channelHandler) {
+ this.channelHandler = channelHandler;
+ }
+
+ @Override
+ public void channelActive(final ChannelHandlerContext ctx) throws
Exception {
+ super.channelActive(ctx);
+ NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel());
+ try {
+ channelHandler.connection(channel);
+ } finally {
+ NettyChannel.removeChannel(ctx.channel());
+ }
+ }
+
+ @Override
+ public void channelInactive(final ChannelHandlerContext ctx) throws
Exception {
+ super.channelInactive(ctx);
+ try {
+ NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel());
+ channelHandler.disConnection(channel);
+ } finally {
+ NettyChannel.removeChannel(ctx.channel());
+ }
+ }
+
+ @Override
+ public void channelRead(final ChannelHandlerContext ctx, final Object msg)
throws Exception {
+ NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel());
+ try {
+ channelHandler.receive(channel, msg);
+ } finally {
+ NettyChannel.removeChannel(ctx.channel());
+ }
+ }
+
+ @Override
+ public void write(final ChannelHandlerContext ctx,
+ final Object msg, final ChannelPromise promise) throws
Exception {
+ super.write(ctx, msg, promise);
+ NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel());
+ try {
+ channelHandler.sent(channel, msg);
+ } finally {
+ NettyChannel.removeChannel(ctx.channel());
+ }
+ }
+
+ @Override
+ public void userEventTriggered(final ChannelHandlerContext ctx, final
Object evt) throws Exception {
+ if (evt instanceof IdleStateEvent) {
+ IdleState state = ((IdleStateEvent) evt).state();
+ NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel());
+ try {
+ switch (state) {
+ case READER_IDLE:
+ case WRITER_IDLE:
+ case ALL_IDLE:
+ channel.close();
+ return;
+ default:
+ break;
+ }
+ } finally {
+ NettyChannel.removeChannel(ctx.channel());
+ }
+ }
+ super.userEventTriggered(ctx, evt);
+ }
+
+ @Override
+ public void exceptionCaught(final ChannelHandlerContext ctx, final
Throwable cause) throws Exception {
+ NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel());
+ channelHandler.caught(channel, cause);
+ }
+
+}
diff --git
a/shenyu-proxy/proxy-remote/src/test/java/org/apache/shenyu/proxy/remote/NettyServerTest.java
b/shenyu-proxy/proxy-remote/src/test/java/org/apache/shenyu/proxy/remote/NettyServerTest.java
new file mode 100644
index 000000000..706a45aa7
--- /dev/null
+++
b/shenyu-proxy/proxy-remote/src/test/java/org/apache/shenyu/proxy/remote/NettyServerTest.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shenyu.proxy.remote;
+
+import org.junit.Test;
+
+/**
+ * NettyServerTest .
+ */
+public class NettyServerTest {
+
+ /**
+ * Test server startup.
+ */
+ @Test
+ public void testServer() {
+ }
+}