Skip to content

Commit

Permalink
better server and client side customization. improve docs
Browse files Browse the repository at this point in the history
  • Loading branch information
aatarasoff committed Sep 12, 2018
1 parent 000066e commit 6bbd91b
Show file tree
Hide file tree
Showing 8 changed files with 95 additions and 35 deletions.
18 changes: 16 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,23 +76,37 @@ public Response getSimpleResponse(@Param("name") String name) {

As you see you could autowire any spring component, service or another bean into it.

In `application.yml` you could provide advertise ip and port as following:
In `application.yml` you could provide advertise ip and port and other properties as following:
```yaml
oneserver:
#required
advertiseIp: 0.0.0.0
port: 10080
#optional
selectorThreadsCount: # default 0
maxWorkersCount: # default 0
minWorkersCount: # default 0
queueTime: # default 0
keepAlive: # default 0
threadPriority: # default 5 or Thread.NORM_PRIORITY
affinity: # default false
```
#### Client side
This part still in progress and there is no very easy way to use it but it is possible.
Client side based on **ribbon** load balancer and `HttpClient` from `one-nio`.

For use it with ribbon you should define your client settings in `application.yml`:
```yaml
cool-app:
ribbon:
listOfServers: 127.0.0.1:10080
#supported client config keys
ConnectTimeout: 1000
ReadTimeout: 10000
PoolMinThreads: 1
PoolMaxThreads: 200
KeepAlive: false
```

They are all the same as in the case of using rest template or feign.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
package info.developerblog.spring.oneserver.client;

import com.netflix.client.ClientException;
import info.developerblog.spring.oneserver.ribbon.OneLoadBalancedHttpClient;
import info.developerblog.spring.oneserver.ribbon.OneLoadBalancerFactory;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import one.nio.http.Response;

/**
* @author alexander.tarasov
*/
@Slf4j
public class OneHttpClient {
private static final Logger log = LoggerFactory.getLogger(OneLoadBalancedHttpClient.class);
OneLoadBalancerFactory loadBalancerFactory;

public OneHttpClient(OneLoadBalancerFactory loadBalancerFactory) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
package info.developerblog.spring.oneserver.ribbon;

import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.TimeUnit;

import com.google.common.collect.Maps;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.netflix.client.config.CommonClientConfigKey;
import com.netflix.client.config.IClientConfig;
import com.netflix.client.config.IClientConfigKey;
import info.developerblog.spring.oneserver.client.OneHttpRequest;
import info.developerblog.spring.oneserver.client.OneHttpResponse;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import one.nio.http.HttpClient;
import one.nio.http.Response;
Expand All @@ -17,30 +19,42 @@
/**
* @author alexander.tarasov
*/
@Slf4j
public class OneLoadBalancedHttpClient {
private ConcurrentMap<String, HttpClient> httpClients = Maps.newConcurrentMap();
private static final Logger log = LoggerFactory.getLogger(OneLoadBalancedHttpClient.class);
private static final IClientConfigKey<Boolean> KeepAlive = new CommonClientConfigKey<Boolean>("KeepAlive") {};

private final int readTimeout;
private final int maxPoolSize;
private Cache<String, HttpClient> httpClients = CacheBuilder.newBuilder()
.expireAfterAccess(10, TimeUnit.MINUTES)
.expireAfterWrite(1, TimeUnit.HOURS)
.removalListener(notification -> ((HttpClient) notification.getValue()).close())
.build();

public OneLoadBalancedHttpClient(IClientConfig clientConfig) {
readTimeout = clientConfig.get(CommonClientConfigKey.ReadTimeout, 10000);
maxPoolSize = clientConfig.get(CommonClientConfigKey.PoolMaxThreads, 50);
private final IClientConfig clientConfig;

OneLoadBalancedHttpClient(IClientConfig clientConfig) {
this.clientConfig = clientConfig;
}

public OneHttpResponse execute(OneHttpRequest request) {
OneHttpResponse execute(OneHttpRequest request) {
int connectTimeout = clientConfig.get(CommonClientConfigKey.ConnectTimeout, 1000);
int readTimeout = clientConfig.get(CommonClientConfigKey.ReadTimeout, 10000);
int minPoolSize = clientConfig.get(CommonClientConfigKey.PoolMinThreads, 0);
int maxPoolSize = clientConfig.get(CommonClientConfigKey.PoolMaxThreads, 50);
boolean keepAlive = clientConfig.get(KeepAlive, false);

String connectionString = request.getUri().getScheme() + "://" +
request.getUri().getHost() + ":" + request.getUri().getPort() +
"?timeout=" + readTimeout +
"&connectTimeout=" + connectTimeout +
"&clientMinPoolSize=" + minPoolSize +
"&clientMaxPoolSize=" + maxPoolSize +
"&keepalive=false";
"&keepalive=" + keepAlive;

try {
return new OneHttpResponse(
httpClients.computeIfAbsent(
httpClients.get(
connectionString,
k -> new HttpClient(new ConnectionString(connectionString))
() -> new HttpClient(new ConnectionString(connectionString))
).invoke(request.toRequest()),
request.getUri()
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
package info.developerblog.spring.oneserver.ribbon;

import java.net.URI;

import org.springframework.cloud.netflix.ribbon.ServerIntrospector;

import com.netflix.client.AbstractLoadBalancerAwareClient;
import com.netflix.client.RequestSpecificRetryHandler;
import com.netflix.client.RetryHandler;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server;
import info.developerblog.spring.oneserver.client.OneHttpRequest;
import info.developerblog.spring.oneserver.client.OneHttpResponse;

import org.springframework.cloud.netflix.ribbon.ServerIntrospector;

import java.net.URI;

import static org.springframework.cloud.netflix.ribbon.RibbonUtils.updateToHttpsIfNeeded;
import static org.springframework.cloud.netflix.ribbon.RibbonUtils.updateToSecureConnectionIfNeeded;

/**
* @author alexander.tarasov
Expand Down Expand Up @@ -47,7 +45,7 @@ public OneHttpResponse execute(OneHttpRequest request,

@Override
public URI reconstructURIWithServer(Server server, URI original) {
URI uri = updateToHttpsIfNeeded(original, this.clientConfig, this.serverIntrospector, server);
URI uri = updateToSecureConnectionIfNeeded(original, this.clientConfig, this.serverIntrospector, server);
return super.reconstructURIWithServer(server, uri);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ public HttpServer httpServer() throws IOException {
serverConfig.selectors = properties.getSelectorThreadsCount();
serverConfig.minWorkers = properties.getMinWorkersCount();
serverConfig.maxWorkers = properties.getMaxWorkersCount();
serverConfig.queueTime = properties.getQueueTime();
serverConfig.keepAlive = properties.getKeepAlive();
serverConfig.threadPriority = properties.getThreadPriority();
serverConfig.affinity = properties.isAffinity();

HttpServer httpServer = new HttpServer(serverConfig);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ public class OneServerProperties {
private int selectorThreadsCount = 0;
private int maxWorkersCount = 0;
private int minWorkersCount = 0;
private int queueTime = 0;
private int keepAlive = 0;
private int threadPriority = Thread.NORM_PRIORITY;
private boolean affinity = false;

public String getAdvertiseIp() {
return advertiseIp;
Expand Down Expand Up @@ -53,4 +57,36 @@ public int getMinWorkersCount() {
public void setMinWorkersCount(int minWorkersCount) {
this.minWorkersCount = minWorkersCount;
}

public int getQueueTime() {
return queueTime;
}

public void setQueueTime(int queueTime) {
this.queueTime = queueTime;
}

public int getThreadPriority() {
return threadPriority;
}

public void setThreadPriority(int threadPriority) {
this.threadPriority = threadPriority;
}

public int getKeepAlive() {
return keepAlive;
}

public void setKeepAlive(int keepAlive) {
this.keepAlive = keepAlive;
}

public boolean isAffinity() {
return affinity;
}

public void setAffinity(boolean affinity) {
this.affinity = affinity;
}
}
2 changes: 0 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,6 @@ subprojects {
}

dependencies {
compileOnly 'org.projectlombok:lombok'

testCompile('org.springframework.boot:spring-boot-starter-test')
}
}
8 changes: 1 addition & 7 deletions example/src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,4 @@ oneserver:

cool-app:
ribbon:
listOfServers: 127.0.0.1:10080
NFLoadBalancerPingInterval: 100
ServerListRefreshInterval: 1000
MaxAutoRetries: 0
MaxAutoRetriesNextServer: 0
OkToRetryOnAllOperations: false
zoneAffinity.minAvailableServers: 2
listOfServers: 127.0.0.1:10080

0 comments on commit 6bbd91b

Please sign in to comment.