yangyoupeng

添加service的LRUCache

...@@ -78,12 +78,14 @@ public class SendResponseFilter extends ZuulFilter { ...@@ -78,12 +78,14 @@ public class SendResponseFilter extends ZuulFilter {
78 private void writeResponse() throws IOException { 78 private void writeResponse() throws IOException {
79 RequestContext context = RequestContext.getCurrentContext(); 79 RequestContext context = RequestContext.getCurrentContext();
80 String response = context.getResponseBody(); 80 String response = context.getResponseBody();
81 + LOG.debug("response [{}]",response);
81 HttpServletResponse servletResponse = context.getResponse(); 82 HttpServletResponse servletResponse = context.getResponse();
82 servletResponse.setCharacterEncoding("UTF-8"); 83 servletResponse.setCharacterEncoding("UTF-8");
83 OutputStream outStream = servletResponse.getOutputStream(); 84 OutputStream outStream = servletResponse.getOutputStream();
84 //发送错误信息 85 //发送错误信息
85 if (response == null && context.getResponseDataStream() == null) { 86 if (response == null && context.getResponseDataStream() == null) {
86 Response responseObject=Response.failedResponse(); 87 Response responseObject=Response.failedResponse();
88 + LOG.info("there is now response body or response steam,just send fail info [{}]",responseObject);
87 writeResponse(new ByteArrayInputStream(responseObject.toJson().getBytes(Charset.forName("UTF-8"))), outStream); 89 writeResponse(new ByteArrayInputStream(responseObject.toJson().getBytes(Charset.forName("UTF-8"))), outStream);
88 return; 90 return;
89 } 91 }
...@@ -94,6 +96,7 @@ public class SendResponseFilter extends ZuulFilter { ...@@ -94,6 +96,7 @@ public class SendResponseFilter extends ZuulFilter {
94 if(context.getThrowable() !=null){ 96 if(context.getThrowable() !=null){
95 Response responseObject=Response.failedResponse(); 97 Response responseObject=Response.failedResponse();
96 responseObject.setMsg(context.getThrowable().getCause().getMessage()); 98 responseObject.setMsg(context.getThrowable().getCause().getMessage());
99 + LOG.info("there is exception when do request ,just send fail info [{}]",responseObject);
97 writeResponse(new ByteArrayInputStream(responseObject.toJson().getBytes(Charset.forName("UTF-8"))), outStream); 100 writeResponse(new ByteArrayInputStream(responseObject.toJson().getBytes(Charset.forName("UTF-8"))), outStream);
98 return; 101 return;
99 } 102 }
......
...@@ -8,6 +8,7 @@ import java.util.Map; ...@@ -8,6 +8,7 @@ import java.util.Map;
8 import javax.servlet.http.HttpServletRequest; 8 import javax.servlet.http.HttpServletRequest;
9 9
10 import org.apache.http.HttpResponse; 10 import org.apache.http.HttpResponse;
11 +import org.apache.http.entity.ContentType;
11 import org.slf4j.Logger; 12 import org.slf4j.Logger;
12 import org.slf4j.LoggerFactory; 13 import org.slf4j.LoggerFactory;
13 import org.springframework.beans.factory.DisposableBean; 14 import org.springframework.beans.factory.DisposableBean;
...@@ -69,6 +70,9 @@ public class TransforFilter extends ZuulFilter implements InitializingBean,Dispo ...@@ -69,6 +70,9 @@ public class TransforFilter extends ZuulFilter implements InitializingBean,Dispo
69 RequestContext context = RequestContext.getCurrentContext(); 70 RequestContext context = RequestContext.getCurrentContext();
70 HttpServletRequest request = context.getRequest(); 71 HttpServletRequest request = context.getRequest();
71 72
73 + LOGGER.info("recieve http request [{}]",request);
74 +
75 +
72 Map<String,Object> headerMap=new HashMap<String,Object>(); 76 Map<String,Object> headerMap=new HashMap<String,Object>();
73 Enumeration<String> headers=request.getHeaderNames(); 77 Enumeration<String> headers=request.getHeaderNames();
74 while(headers.hasMoreElements()){ 78 while(headers.hasMoreElements()){
...@@ -96,7 +100,7 @@ public class TransforFilter extends ZuulFilter implements InitializingBean,Dispo ...@@ -96,7 +100,7 @@ public class TransforFilter extends ZuulFilter implements InitializingBean,Dispo
96 } catch (Exception e) { 100 } catch (Exception e) {
97 //对于异常。应该通知下异常处理 101 //对于异常。应该通知下异常处理
98 e.printStackTrace(); 102 e.printStackTrace();
99 - LOGGER.error("fail to read service info about {},because {} ",serviceName,e.getMessage()); 103 + LOGGER.error("fail to read service info about [{}],because [{}] ",serviceName,e.getMessage());
100 } 104 }
101 handlerServiceUnvaliable(context, serviceName, serviceInfo); 105 handlerServiceUnvaliable(context, serviceName, serviceInfo);
102 106
......
...@@ -35,6 +35,12 @@ public class ServiceLifeCycleChecker implements LifeCycleChecker { ...@@ -35,6 +35,12 @@ public class ServiceLifeCycleChecker implements LifeCycleChecker {
35 @Override 35 @Override
36 public void run() { 36 public void run() {
37 AbstractService service=serviceRef.get(); 37 AbstractService service=serviceRef.get();
38 +
39 + if(service ==null || serviceRef.get().isClosed() ){
40 + LOGGER.info ("dubbo service is closed now");
41 + throw new RuntimeException(String.format("throw an exception to terminate the thread,the service %s is closed ", serviceInfo));
42 + }
43 +
38 Long startTime=service.getStartTime(); 44 Long startTime=service.getStartTime();
39 DateTime startDateTime=new DateTime(startTime); 45 DateTime startDateTime=new DateTime(startTime);
40 46
...@@ -45,10 +51,6 @@ public class ServiceLifeCycleChecker implements LifeCycleChecker { ...@@ -45,10 +51,6 @@ public class ServiceLifeCycleChecker implements LifeCycleChecker {
45 service.setClosed(true); 51 service.setClosed(true);
46 } 52 }
47 53
48 - if(service ==null || serviceRef.get().isClosed() ){
49 - LOGGER.info ("dubbo service is closed now");
50 - throw new RuntimeException(String.format("throw an exception to terminate the thread,the service %s is closed ", serviceInfo));
51 - }
52 try{ 54 try{
53 String status = (String) echoService.$echo("OK"); // 回声测试可用性 55 String status = (String) echoService.$echo("OK"); // 回声测试可用性
54 if(!status.equals("OK")){ 56 if(!status.equals("OK")){
......
...@@ -43,7 +43,9 @@ public class BeanConfiguration { ...@@ -43,7 +43,9 @@ public class BeanConfiguration {
43 43
44 @Bean 44 @Bean
45 public EhCacheFactoryBean ehcache4UserDetails(){ 45 public EhCacheFactoryBean ehcache4UserDetails(){
46 - return new EhCacheFactoryBean(); 46 + EhCacheFactoryBean factory= new EhCacheFactoryBean();
47 + factory.diskPersistent(false);
48 + return factory;
47 } 49 }
48 50
49 @Bean 51 @Bean
......
...@@ -17,10 +17,12 @@ import java.util.concurrent.atomic.AtomicReference; ...@@ -17,10 +17,12 @@ import java.util.concurrent.atomic.AtomicReference;
17 import javax.servlet.http.HttpServletRequest; 17 import javax.servlet.http.HttpServletRequest;
18 18
19 import org.apache.http.HttpRequest; 19 import org.apache.http.HttpRequest;
20 +import org.apache.http.entity.ContentType;
20 import org.apache.http.HttpResponse; 21 import org.apache.http.HttpResponse;
21 import org.apache.http.client.methods.RequestBuilder; 22 import org.apache.http.client.methods.RequestBuilder;
22 import org.apache.http.entity.InputStreamEntity; 23 import org.apache.http.entity.InputStreamEntity;
23 import org.apache.http.message.BasicHttpRequest; 24 import org.apache.http.message.BasicHttpRequest;
25 +import org.mockito.internal.matchers.ContainsExtraTypeInformation;
24 import org.slf4j.Logger; 26 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory; 27 import org.slf4j.LoggerFactory;
26 import org.springframework.util.ObjectUtils; 28 import org.springframework.util.ObjectUtils;
...@@ -44,6 +46,7 @@ import com.zhaoonline.support.gateway.config.GWConstants; ...@@ -44,6 +46,7 @@ import com.zhaoonline.support.gateway.config.GWConstants;
44 import com.zhaoonline.support.gateway.utils.Utils; 46 import com.zhaoonline.support.gateway.utils.Utils;
45 47
46 public class DubboService extends AbstractService<HttpServletRequest, HttpResponse> { 48 public class DubboService extends AbstractService<HttpServletRequest, HttpResponse> {
49 + private static final String APPLICATION_JSON_MIME_TYPE = "application/json";
47 private ApiClassLoaderManager apiClassLoaderManager=ApiClassLoaderManager.INSTANCE; 50 private ApiClassLoaderManager apiClassLoaderManager=ApiClassLoaderManager.INSTANCE;
48 private static final int UNKOWN_CONTENT_LENGTH = -1; 51 private static final int UNKOWN_CONTENT_LENGTH = -1;
49 private static final Logger LOG = LoggerFactory.getLogger(DubboService.class); 52 private static final Logger LOG = LoggerFactory.getLogger(DubboService.class);
...@@ -86,6 +89,12 @@ public class DubboService extends AbstractService<HttpServletRequest, HttpRespon ...@@ -86,6 +89,12 @@ public class DubboService extends AbstractService<HttpServletRequest, HttpRespon
86 if(!isAvailable()){ 89 if(!isAvailable()){
87 throw new GatewayException(String.format("target service:%s is unavailable not ",servicInfo.getServiceName())); 90 throw new GatewayException(String.format("target service:%s is unavailable not ",servicInfo.getServiceName()));
88 } 91 }
92 +
93 + final String contentType = request.getContentType();
94 + if (contentType == null || !(contentType.startsWith(APPLICATION_JSON_MIME_TYPE))) {
95 + throw new GatewayException(String.format("request context type must be set as %s ",APPLICATION_JSON_MIME_TYPE));
96 + }
97 +
89 Object dubboservice = getAutomicReference().get(); 98 Object dubboservice = getAutomicReference().get();
90 //http访问请求中必须带有需要访问method的名称,因为dubbo是rpc协议。 99 //http访问请求中必须带有需要访问method的名称,因为dubbo是rpc协议。
91 String accessMethod = getAccessMethod(request); 100 String accessMethod = getAccessMethod(request);
......
1 +package com.zhaoonline.support.gateway.service;
2 +
3 +import java.util.HashSet;
4 +import java.util.Iterator;
5 +import java.util.Map.Entry;
6 +import java.util.Set;
7 +import java.util.concurrent.ConcurrentHashMap;
8 +import java.util.concurrent.ConcurrentHashMap.KeySetView;
9 +
10 +
11 +public class ServiceLRUCache {
12 + private ConcurrentHashMap<String, AbstractService> serviceLRUcache = null;
13 + private Entry first;
14 + private Entry last;
15 + private int capacity = 0;
16 + public ServiceLRUCache() {
17 + this(200);
18 + }
19 + public ServiceLRUCache(int capacity) {
20 + this.capacity = capacity;
21 + this.serviceLRUcache = new ConcurrentHashMap<String, AbstractService>(200);
22 + }
23 + /**
24 + * serialVersionUID:TODO
25 + */
26 + private static final long serialVersionUID = -8224662589517146643L;
27 +
28 + public synchronized AbstractService put(String key, AbstractService value) {
29 + Entry entry = getEntry(key);
30 + if (entry == null) {
31 + if (serviceLRUcache.size() >= capacity) {
32 + serviceLRUcache.remove(last.key);
33 + removeLast();
34 + }
35 + entry = new Entry();
36 + entry.key = key;
37 + }else{
38 + //因为覆盖了原来的key,所以要讲service的关闭,防止内存溢出,
39 + //另外需要注意的是,此时内存中并不能立刻被销毁,因为在servicelifechecher中还存在对value的reference引用。
40 + //
41 + entry.value.setClosed(true);
42 + entry.value=null;
43 + }
44 + entry.value = value;
45 + moveToFirst(entry);
46 + return serviceLRUcache.put(key, value);
47 + }
48 +
49 + public synchronized AbstractService get(String key) {
50 + Entry entry = getEntry(key);
51 + if (entry == null){
52 + return null;
53 + }
54 + moveToFirst(entry);
55 + return entry.value;
56 + }
57 +
58 + public synchronized void remove(String key) {
59 + Entry entry = getEntry(key);
60 + if (entry != null) {
61 + closeService(entry);
62 + if (entry.pre != null)
63 + entry.pre.next = entry.next;
64 + if (entry.next != null)
65 + entry.next.pre = entry.pre;
66 + if (entry == first)
67 + first = entry.next;
68 + if (entry == last)
69 + last = entry.pre;
70 + }
71 + serviceLRUcache.remove(key);
72 + }
73 + private void closeService(Entry entry) {
74 + entry.value.setClosed(true);
75 + entry.value.destory();
76 + entry.value=null;
77 + }
78 +
79 +
80 + private void removeLast() {
81 + if (last != null) {
82 + closeService(last);
83 + last = last.pre;
84 + if (last == null)
85 + first = null;
86 + else
87 + last.next = null;
88 +
89 + }
90 + }
91 +
92 + private void moveToFirst(Entry entry) {
93 + if (entry == first)
94 + return;
95 + if (entry.pre != null)
96 + entry.pre.next = entry.next;
97 + if (entry.next != null)
98 + entry.next.pre = entry.pre;
99 + if (entry == last)
100 + last = last.pre;
101 + if (first == null || last == null) {
102 + first = last = entry;
103 + return;
104 + }
105 + entry.next = first;
106 + first.pre = entry;
107 + first = entry;
108 + entry.pre = null;
109 + }
110 +
111 + private Entry getEntry(String key) {
112 + AbstractService service = serviceLRUcache.get(key);
113 + if (service == null) {
114 + return null;
115 + }
116 + Entry entry = new Entry();
117 + entry.key = key;
118 + entry.value = service;
119 + return entry;
120 + }
121 +
122 + @Override
123 + public String toString() {
124 + StringBuilder sb = new StringBuilder();
125 + Entry entry = first;
126 + while (entry != null) {
127 + sb.append(String.format("%s:%s ", entry.key, entry.value));
128 + entry = entry.next;
129 + }
130 + return sb.toString();
131 + }
132 +
133 + static class Entry {
134 + String key;
135 + AbstractService value;
136 + Entry pre;
137 + Entry next;
138 + }
139 +
140 + public int getSize() {
141 + return serviceLRUcache.size();
142 + }
143 +
144 +
145 + public Set<String> keySet(){
146 + Set<String> keSet=new HashSet<String>();
147 + KeySetView<String, AbstractService> keysSetView= serviceLRUcache.keySet();
148 + Iterator<String> iter=keysSetView.iterator();
149 + while(iter.hasNext()){
150 + String key=iter.next();
151 + keSet.add(key);
152 + }
153 + return keSet;
154 + }
155 +}
...@@ -17,7 +17,8 @@ public enum ServiceManager{ ...@@ -17,7 +17,8 @@ public enum ServiceManager{
17 17
18 INSTANCE; 18 INSTANCE;
19 private ConcurrentHashMap<String , HTTPService> httpServiceCache=new ConcurrentHashMap<>(); 19 private ConcurrentHashMap<String , HTTPService> httpServiceCache=new ConcurrentHashMap<>();
20 - private ConcurrentHashMap<String , DubboService> dubboServiceCache=new ConcurrentHashMap<>(); 20 +// private ConcurrentHashMap<String , DubboService> dubboServiceCache=new ConcurrentHashMap<>();
21 + private ServiceLRUCache dubboServiceCache=new ServiceLRUCache();
21 private static final Logger LOG = LoggerFactory.getLogger(ServiceManager.class); 22 private static final Logger LOG = LoggerFactory.getLogger(ServiceManager.class);
22 private LifeCycleCheckerManager lifeCycleCheckerManager=LifeCycleCheckerManager.INSTANCE; 23 private LifeCycleCheckerManager lifeCycleCheckerManager=LifeCycleCheckerManager.INSTANCE;
23 24
...@@ -44,11 +45,19 @@ public enum ServiceManager{ ...@@ -44,11 +45,19 @@ public enum ServiceManager{
44 entry.getValue().destory(); 45 entry.getValue().destory();
45 LOG.info("HTTP Service:{} has bean shutdown",entry.getKey()); 46 LOG.info("HTTP Service:{} has bean shutdown",entry.getKey());
46 } 47 }
47 - Set<Entry<String, DubboService>> dubboEntrySet=dubboServiceCache.entrySet(); 48 +
48 - for(Entry<String, DubboService> entry:dubboEntrySet){ 49 +
49 - entry.getValue().destory(); 50 + Set<String> dubboEntrySet=dubboServiceCache.keySet();
50 - LOG.info("Dubbo Service:{} has bean shutdown",entry.getKey()); 51 + for(String key:dubboEntrySet){
52 + dubboServiceCache.remove(key);
53 + LOG.info("Dubbo Service:{} has bean shutdown",key);
51 } 54 }
55 +
56 +// Set<Entry<String, DubboService>> dubboEntrySet=dubboServiceCache.entrySet();
57 +// for(Entry<String, DubboService> entry:dubboEntrySet){
58 +// entry.getValue().destory();
59 +// LOG.info("Dubbo Service:{} has bean shutdown",entry.getKey());
60 +// }
52 } 61 }
53 62
54 /** 63 /**
...@@ -59,24 +68,27 @@ public enum ServiceManager{ ...@@ -59,24 +68,27 @@ public enum ServiceManager{
59 * @return DubboService<BR> 68 * @return DubboService<BR>
60 */ 69 */
61 public synchronized DubboService buildDubboServiceFrom(ServiceInfo serviceInfo,GateWayConfiguration config) { 70 public synchronized DubboService buildDubboServiceFrom(ServiceInfo serviceInfo,GateWayConfiguration config) {
62 - DubboService cachedService = dubboServiceCache.get(serviceInfo.getServiceInterface()); 71 + String serviceName=serviceInfo.getServiceName();
72 + DubboService cachedService = (DubboService) dubboServiceCache.get(serviceName);
63 if(cachedService == null){ 73 if(cachedService == null){
64 - LOG.info("no cache for dubbo service {},create new instance for service",serviceInfo.getServiceInterface()); 74 + LOG.info("no cache for dubbo service [{}],create new instance for service",serviceInfo.getServiceName());
65 DubboService dubboSerivce=new DubboService(serviceInfo); 75 DubboService dubboSerivce=new DubboService(serviceInfo);
66 try { 76 try {
67 dubboSerivce.init(); 77 dubboSerivce.init();
68 monitorStatus(dubboSerivce,config); 78 monitorStatus(dubboSerivce,config);
69 } catch (Exception e) { 79 } catch (Exception e) {
70 - LOG.info("fail to init the dubbo service interface {},cause by {}",serviceInfo.getServiceInterface(),e.getMessage()); 80 + LOG.info("fail to init the dubbo service interface [{}],cause by [{}]",serviceInfo,e.getMessage());
71 e.printStackTrace(); 81 e.printStackTrace();
72 return null; 82 return null;
73 } 83 }
74 - dubboServiceCache.put(serviceInfo.getServiceInterface(), dubboSerivce); 84 + LOG.info("cache dubbo service with key [{}]",serviceName);
85 + dubboServiceCache.put(serviceName,dubboSerivce);
75 return dubboSerivce; 86 return dubboSerivce;
76 }else{ 87 }else{
88 + LOG.info("get dubbo service from cache with key [{}]",serviceName);
77 if(cachedService.isClosed()){ 89 if(cachedService.isClosed()){
78 LOG.info("the cached dubbo service interface {} is closed by {},just return null",serviceInfo.getServiceInterface(),LifeCycleCheckerManager.class.getName()); 90 LOG.info("the cached dubbo service interface {} is closed by {},just return null",serviceInfo.getServiceInterface(),LifeCycleCheckerManager.class.getName());
79 - dubboServiceCache.remove(serviceInfo.getServiceInterface()); 91 + dubboServiceCache.remove(serviceName);
80 cachedService=null; 92 cachedService=null;
81 } 93 }
82 } 94 }
......
...@@ -24,7 +24,7 @@ public static void main(String[] args) throws JsonProcessingException { ...@@ -24,7 +24,7 @@ public static void main(String[] args) throws JsonProcessingException {
24 TransportClient clinet=ElasticClientFactory.createClient(config); 24 TransportClient clinet=ElasticClientFactory.createClient(config);
25 ESServiceInfoLoader esUserInfoReposity=new ESServiceInfoLoader(clinet); 25 ESServiceInfoLoader esUserInfoReposity=new ESServiceInfoLoader(clinet);
26 26
27 - ServiceInfo newServiceInfo = localHttpService("wxtest"); 27 + ServiceInfo newServiceInfo = dubboService("wxtest");
28 boolean indexResponse=esUserInfoReposity.addServiceInfo(newServiceInfo); 28 boolean indexResponse=esUserInfoReposity.addServiceInfo(newServiceInfo);
29 29
30 // ServiceInfo serviceInfo=esUserInfoReposity.findServiceInfo("dubbo2"); 30 // ServiceInfo serviceInfo=esUserInfoReposity.findServiceInfo("dubbo2");
...@@ -48,7 +48,7 @@ private static ServiceInfo dubboService(String serviceName) { ...@@ -48,7 +48,7 @@ private static ServiceInfo dubboService(String serviceName) {
48 48
49 HostPort hostport=new HostPort(); 49 HostPort hostport=new HostPort();
50 hostport.setProtocol("zookeeper"); 50 hostport.setProtocol("zookeeper");
51 - hostport.setHost("192.168.0.205"); 51 + hostport.setHost("192.168.0.112");
52 hostport.setPort(2181); 52 hostport.setPort(2181);
53 List<HostPort> hostPorts=Arrays.asList(hostport); 53 List<HostPort> hostPorts=Arrays.asList(hostport);
54 servicInfo.setHostports(hostPorts); 54 servicInfo.setHostports(hostPorts);
......
1 +package com.zhaoonline.support.gateway.service;
2 +
3 +import java.io.IOException;
4 +import java.lang.reflect.InvocationTargetException;
5 +
6 +import javax.servlet.http.HttpServletRequest;
7 +
8 +import org.apache.http.HttpResponse;
9 +import org.junit.Assert;
10 +import org.junit.Test;
11 +
12 +import com.netflix.zuul.context.RequestContext;
13 +
14 +public class TestServiceLRUCache {
15 +
16 + @Test
17 + public void test(){
18 + ServiceLRUCache cahce=new ServiceLRUCache(3);
19 +
20 + AbstractService service =new HTTPService(null);
21 + AbstractService service1 =new HTTPService(null);
22 + AbstractService service2 =new HTTPService(null);
23 + AbstractService service3 =new HTTPService(null);
24 + cahce.put("1", service);
25 + cahce.put("2", service1);
26 + cahce.put("3", service2);
27 + Assert.assertFalse(service.isClosed());
28 + Assert.assertFalse(service1.isClosed());
29 + Assert.assertFalse(service2.isClosed());
30 + Assert.assertEquals(3, cahce.getSize());
31 + cahce.put("4", service3);
32 + cahce.put("5", service3);
33 + cahce.put("4", service3);
34 + cahce.put("5", service3);
35 + Assert.assertTrue(service.isClosed());
36 + Assert.assertTrue(service1.isClosed());
37 + Assert.assertFalse(service2.isClosed());
38 + Assert.assertEquals(3, cahce.getSize());
39 +
40 +
41 + }
42 +}