├── .gitignore
├── LICENSE
├── README.md
├── pom.xml
├── s2g-zuul-core
├── pom.xml
└── src
│ └── main
│ ├── java
│ └── io
│ │ └── spring2go
│ │ ├── tools
│ │ ├── InfoBoard.java
│ │ ├── common
│ │ │ ├── AbstractHandler.java
│ │ │ ├── ClassStats.java
│ │ │ ├── GCStats.java
│ │ │ ├── LogHandler.java
│ │ │ ├── MemoryStats.java
│ │ │ ├── OperatingSystemStats.java
│ │ │ ├── Stats.java
│ │ │ ├── StatsGetter.java
│ │ │ ├── StatsHandler.java
│ │ │ ├── StatusInfo.java
│ │ │ └── ThreadStats.java
│ │ ├── servlet
│ │ │ ├── EnvServlet.java
│ │ │ ├── HystrixServlet.java
│ │ │ ├── PropsServlet.java
│ │ │ ├── StaticServlet.java
│ │ │ └── StatusServlet.java
│ │ ├── stat
│ │ │ ├── ClassStatsGetter.java
│ │ │ ├── GCStatsGetter.java
│ │ │ ├── JvmStatsReporter.java
│ │ │ ├── MemoryStatsGetter.java
│ │ │ ├── OperatingSystemStatsGetter.java
│ │ │ └── ThreadStatsGetter.java
│ │ └── util
│ │ │ ├── ByteUtil.java
│ │ │ └── TimeUtil.java
│ │ └── zuul
│ │ ├── common
│ │ ├── CatContext.java
│ │ ├── Constants.java
│ │ ├── ExecutionStatus.java
│ │ ├── FilterInfo.java
│ │ ├── HttpServletRequestWrapper.java
│ │ ├── HttpServletResponseWrapper.java
│ │ ├── IDynamicCodeCompiler.java
│ │ ├── IFilterFactory.java
│ │ ├── IFilterUsageNotifier.java
│ │ ├── IMonitor.java
│ │ ├── INamedCount.java
│ │ ├── ITracer.java
│ │ ├── IZuulFilter.java
│ │ ├── IZuulFilterDao.java
│ │ ├── IZuulFilterDaoBuilder.java
│ │ ├── ServletInputStreamWrapper.java
│ │ ├── ZuulException.java
│ │ ├── ZuulFilterResult.java
│ │ └── ZuulHeaders.java
│ │ ├── context
│ │ └── RequestContext.java
│ │ ├── core
│ │ ├── FilterFileManager.java
│ │ ├── FilterLoader.java
│ │ ├── FilterProcessor.java
│ │ ├── LogConfigurator.java
│ │ ├── ZuulCallable.java
│ │ └── ZuulRunner.java
│ │ ├── filters
│ │ ├── DefaultFilterFactory.java
│ │ ├── FilterRegistry.java
│ │ ├── FilterScriptManagerServlet.java
│ │ ├── FilterVerifier.java
│ │ ├── HttpZuulFilterDao.java
│ │ ├── HttpZuulFilterDaoBuilder.java
│ │ ├── HystrixZuulFilterDao.java
│ │ ├── JDBCZuulFilterDao.java
│ │ ├── JDBCZuulFilterDaoBuilder.java
│ │ ├── ZuulFilter.java
│ │ ├── ZuulFilterDaoFactory.java
│ │ └── ZuulFilterPoller.java
│ │ ├── groovy
│ │ ├── GroovyCompiler.java
│ │ └── GroovyFileFilter.java
│ │ ├── hystrix
│ │ ├── DiscoveryServerList.java
│ │ ├── HttpClientResponse.java
│ │ ├── RestClient.java
│ │ ├── RestClientFactory.java
│ │ ├── RibbonRequestCommandForSemaphoreIsolation.java
│ │ ├── RibbonRequestCommandForThreadIsolation.java
│ │ ├── RibbonZuulCommon.java
│ │ ├── ZuulCommandHelper.java
│ │ ├── ZuulRequestCommandForSemaphoreIsolation.java
│ │ └── ZuulRequestCommandForThreadIsolation.java
│ │ ├── mobile
│ │ ├── DebugHeader.java
│ │ ├── DebugModeSetter.java
│ │ ├── DebugRequest.java
│ │ ├── DebugResponse.java
│ │ ├── ErrorResponse.java
│ │ ├── HealthCheck.java
│ │ ├── MobileAddTimeStamp.java
│ │ ├── MobileExecuteRoute.java
│ │ ├── SendResponse.java
│ │ ├── Stats.java
│ │ └── TestRouting.java
│ │ ├── monitoring
│ │ ├── Counter.java
│ │ ├── CounterFactory.java
│ │ ├── ErrorStatsData.java
│ │ ├── ErrorStatsManager.java
│ │ ├── MetricPoller.java
│ │ ├── MonitorRegistry.java
│ │ ├── NamedCountingMonitor.java
│ │ ├── RouteErrorMonitor.java
│ │ ├── RouteStatusCodeMonitor.java
│ │ ├── ServoMonitor.java
│ │ ├── StatManager.java
│ │ ├── Tracer.java
│ │ └── TracerFactory.java
│ │ ├── servlet
│ │ └── CatServletFilter.java
│ │ └── util
│ │ ├── AdminFilterUtil.java
│ │ ├── Debug.java
│ │ ├── DeepCopy.java
│ │ ├── HTTPRequestUtil.java
│ │ ├── HttpUtil.java
│ │ ├── IPUtil.java
│ │ ├── JSONUtils.java
│ │ ├── MonitoringUtil.java
│ │ ├── S2gUtil.java
│ │ ├── SleepUtil.java
│ │ └── StringUtil.java
│ └── resources
│ └── content
│ ├── index.html
│ └── jquery-2.1.1.min.js
└── s2g-zuul-mobile
├── pom.xml
└── src
├── main
├── java
│ └── io
│ │ └── spring2go
│ │ └── zuul
│ │ └── servlet
│ │ ├── AsyncZuulListener.java
│ │ ├── AsyncZuulServlet.java
│ │ ├── InitializeServletListener.java
│ │ └── SyncZuulServlet.java
├── resources
│ ├── .gitignore
│ ├── META-INF
│ │ └── app.properties
│ ├── db
│ │ └── schema.sql
│ ├── mobile_zuul-logback-prod.xml
│ ├── mobile_zuul-logback-test.xml
│ ├── mobile_zuul-logback-uat.xml
│ ├── mobile_zuul-logback.xml
│ ├── mobile_zuul-prod.properties
│ ├── mobile_zuul-test.properties
│ ├── mobile_zuul-uat.properties
│ └── mobile_zuul.properties
└── webapp
│ ├── WEB-INF
│ └── web.xml
│ └── admin
│ └── filterLoader.jsp
└── scripts
├── error
└── ErrorResponse.groovy
├── post
├── AddTimeStamp.groovy
├── DebugHeader.groovy
├── DebugResponse.groovy
├── SendResponse.groovy
└── Stats.groovy
├── pre
├── DebugModeSetter.groovy
├── DebugRequest.groovy
├── HealthCheck.groovy
└── TestRoute.groovy
└── route
├── ExecuteRibbon.groovy
└── ExecuteRoute.groovy
/.gitignore:
--------------------------------------------------------------------------------
1 | target/
2 | !.mvn/wrapper/maven-wrapper.jar
3 |
4 | ### STS ###
5 | .apt_generated
6 | .classpath
7 | .factorypath
8 | .project
9 | .settings
10 | .springBeans
11 |
12 | ### IntelliJ IDEA ###
13 | .idea
14 | *.iws
15 | *.iml
16 | *.ipr
17 |
18 | *.iml
19 | .gradle
20 | local.properties
21 | .idea/workspace.xml
22 | .idea/libraries
23 | .DS_Store
24 | build/
25 | captures/
26 | .externalNativeBuild
27 |
28 | ### NetBeans ###
29 | nbproject/private/
30 | build/
31 | nbbuild/
32 | dist/
33 | nbdist/
34 | .nb-gradle/
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 spring2go.com
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # s2g-zuul
2 | Spring2go定制版Netflix zuul
3 |
4 | ## 注意!!!
5 |
6 | 1. 本项目为微服务课程讲解开发,代码仅供学习参考,如需生产化,需要做生产化扩展+严格测试!!!另外请考虑Spring Cloud Zuul。
7 | 2. 注意本项目依赖[CAT3.0](https://github.com/dianping/cat)客户端,启动前需要先CAT客户端配置工作,否则Servlet会启不来,步骤如下描述。
8 |
9 | ## 建议
10 |
11 | s2g-zuul源码建议使用较新版本的[Eclipse IDE for Java EE Developer](https://www.eclipse.org/downloads/packages/release/2019-03/r/eclipse-ide-enterprise-java-developers
12 | )进行导入,它可以自动感知Servlet Web项目,可在Eclipse+Tomcat里头直接调试源码,方便排查问题。
13 |
14 | ## 启动 cat 客户端前的准备工作
15 |
16 | 1. 创建 `/data/appdatas/cat` 目录
17 |
18 | 确保你具有这个目录的读写权限。
19 |
20 | 2. 创建 `/data/applogs/cat` 目录 (可选)
21 |
22 | 这个目录是用于存放运行时日志的,这将会对调试提供很大帮助,同样需要读写权限。
23 |
24 | 3. 创建 `/data/appdatas/cat/client.xml`,内容如下
25 |
26 | ```xml
27 |
28 |
29 |
30 |
31 |
32 |
33 | ```
34 |
35 | > 如果不实际使用CAT,只是验证Zuul功能,则上面CAT服务器地址可以随意填;如果要实际启用CAT服务器,则上面需要填写你的CAT server地址。
36 |
37 | 注意,上述目录和zuul在要在同一逻辑盘下。
38 |
--------------------------------------------------------------------------------
/s2g-zuul-core/src/main/java/io/spring2go/tools/InfoBoard.java:
--------------------------------------------------------------------------------
1 | package io.spring2go.tools;
2 |
3 | import org.eclipse.jetty.server.Server;
4 | import org.eclipse.jetty.server.session.SessionHandler;
5 | import org.eclipse.jetty.servlet.ServletContextHandler;
6 | import org.eclipse.jetty.servlet.ServletHolder;
7 | import org.slf4j.Logger;
8 | import org.slf4j.LoggerFactory;
9 |
10 | import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServlet;
11 |
12 | import io.spring2go.tools.common.StatusInfo;
13 | import io.spring2go.tools.servlet.EnvServlet;
14 | import io.spring2go.tools.servlet.HystrixServlet;
15 | import io.spring2go.tools.servlet.PropsServlet;
16 | import io.spring2go.tools.servlet.StaticServlet;
17 | import io.spring2go.tools.servlet.StatusServlet;
18 | import io.spring2go.tools.stat.JvmStatsReporter;
19 |
20 | public class InfoBoard {
21 | private Logger logger = LoggerFactory.getLogger(InfoBoard.class);
22 |
23 | private String appName;
24 | private Server server;
25 |
26 | private volatile boolean running = false;
27 |
28 | private StatusInfo statusInfo;
29 | private JvmStatsReporter jvmStatsReporter;
30 |
31 | public InfoBoard(String appName, int port) {
32 | this.appName = appName;
33 | this.server = new Server(port);
34 | this.statusInfo = new StatusInfo();
35 | this.jvmStatsReporter = new JvmStatsReporter(appName, 60000);
36 | this.jvmStatsReporter.addStatsHandler(statusInfo);
37 | this.jvmStatsReporter.start();
38 | try {
39 | ServletContextHandler handler = new ServletContextHandler();
40 | handler.setContextPath("/");
41 |
42 | handler.setSessionHandler(new SessionHandler());
43 |
44 | handler.addServlet(EnvServlet.class, "/api/env");
45 | handler.addServlet(PropsServlet.class, "/api/props");
46 | handler.addServlet(StaticServlet.class, "/*");
47 | handler.addServlet(HystrixServlet.class, "/breaker");
48 | handler.addServlet(HystrixMetricsStreamServlet.class, "/hystrix.stream");
49 | handler.addServlet(new ServletHolder(new StatusServlet(statusInfo)), "/api/status");
50 |
51 | server.setHandler(handler);
52 |
53 | } catch (Exception e) {
54 | logger.error("start jetty error!", e);
55 | }
56 |
57 | }
58 |
59 | public synchronized void start() {
60 | if (!running) {
61 | try {
62 | server.start();
63 | running = true;
64 | } catch (Exception e) {
65 | logger.error("Exception in Starting " + this.getClass().getSimpleName(), e);
66 | }
67 | }
68 | }
69 |
70 | public synchronized void shutdown() {
71 | if (running) {
72 | try {
73 | server.stop();
74 | running = false;
75 | } catch (Exception e) {
76 | logger.error("Exception in Stopping " + this.getClass().getSimpleName(), e);
77 | if (!server.isStarted() && !server.isStarting())
78 | running = false;
79 | }
80 | }
81 | }
82 |
83 | public boolean isRunning() {
84 | return running;
85 | }
86 |
87 | }
88 |
--------------------------------------------------------------------------------
/s2g-zuul-core/src/main/java/io/spring2go/tools/common/AbstractHandler.java:
--------------------------------------------------------------------------------
1 | package io.spring2go.tools.common;
2 |
3 |
4 |
5 | public abstract class AbstractHandler implements StatsHandler {
6 | @Override
7 | public void process(Stats stats) {
8 | if(stats == null) return;
9 |
10 | if(stats instanceof ClassStats) processClassStats((ClassStats) stats);
11 | else if(stats instanceof ThreadStats) processThreadStats((ThreadStats) stats);
12 | else if(stats instanceof MemoryStats) processMemoryStats((MemoryStats) stats);
13 | else if(stats instanceof GCStats) processGCStats((GCStats) stats);
14 | else if(stats instanceof OperatingSystemStats) processOperatingSystemStats((OperatingSystemStats) stats);
15 | }
16 |
17 | protected abstract void processGCStats(GCStats stats);
18 |
19 | protected abstract void processMemoryStats(MemoryStats stats);
20 |
21 | protected abstract void processThreadStats(ThreadStats stats);
22 |
23 | protected abstract void processClassStats(ClassStats stats);
24 |
25 | protected abstract void processOperatingSystemStats(OperatingSystemStats stats);
26 | }
27 |
--------------------------------------------------------------------------------
/s2g-zuul-core/src/main/java/io/spring2go/tools/common/ClassStats.java:
--------------------------------------------------------------------------------
1 | package io.spring2go.tools.common;
2 |
3 |
4 |
5 | public class ClassStats implements Stats {
6 |
7 | private int currentClassCount;
8 | private long beenLoadedClassCount;
9 | private long beenUnloadedClassCount;
10 |
11 | public int getCurrentClassCount() {
12 | return currentClassCount;
13 | }
14 |
15 | public void setCurrentClassCount(int currentClassCount) {
16 | this.currentClassCount = currentClassCount;
17 | }
18 |
19 | public long getBeenLoadedClassCount() {
20 | return beenLoadedClassCount;
21 | }
22 |
23 | public void setBeenLoadedClassCount(long beenLoadedClassCount) {
24 | this.beenLoadedClassCount = beenLoadedClassCount;
25 | }
26 |
27 | public long getBeenUnloadedClassCount() {
28 | return beenUnloadedClassCount;
29 | }
30 |
31 | public void setBeenUnloadedClassCount(long beenUnloadedClassCount) {
32 | this.beenUnloadedClassCount = beenUnloadedClassCount;
33 | }
34 |
35 | @Override
36 | public String toString() {
37 | return "\nClassStats{" +
38 | "\n\tcurrentClassCount=" + currentClassCount +
39 | ", \n\tbeenLoadedClassCount=" + beenLoadedClassCount +
40 | ", \n\tbeenUnloadedClassCount=" + beenUnloadedClassCount +
41 | "\n}";
42 | }
43 |
44 | @Override
45 | public String toJsonStr() {
46 | return "{" +
47 | "\"currentClassCount\":\"" + currentClassCount +
48 | "\", \"beenLoadedClassCount\":\"" + beenLoadedClassCount +
49 | "\", \"beenUnloadedClassCount\":\"" + beenUnloadedClassCount +
50 | "\"}";
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/s2g-zuul-core/src/main/java/io/spring2go/tools/common/GCStats.java:
--------------------------------------------------------------------------------
1 | package io.spring2go.tools.common;
2 |
3 |
4 | public class GCStats implements Stats {
5 | private long minorGcCount;
6 | private long minorGcTime;
7 |
8 | private long fullGcCount;
9 | private long fullGcTime;
10 |
11 | private long otherGcCount;
12 | private long otherGcTime;
13 |
14 |
15 | public long getMinorGcCount() {
16 | return minorGcCount;
17 | }
18 |
19 | public void setMinorGcCount(long minorGcCount) {
20 | this.minorGcCount = minorGcCount;
21 | }
22 |
23 | public long getMinorGcTime() {
24 | return minorGcTime;
25 | }
26 |
27 | public void setMinorGcTime(long minorGcTime) {
28 | this.minorGcTime = minorGcTime;
29 | }
30 |
31 | public long getFullGcCount() {
32 | return fullGcCount;
33 | }
34 |
35 | public void setFullGcCount(long fullGcCount) {
36 | this.fullGcCount = fullGcCount;
37 | }
38 |
39 | public long getFullGcTime() {
40 | return fullGcTime;
41 | }
42 |
43 | public void setFullGcTime(long fullGcTime) {
44 | this.fullGcTime = fullGcTime;
45 | }
46 |
47 | public long getOtherGcCount() {
48 | return otherGcCount;
49 | }
50 |
51 | public void setOtherGcCount(long otherGcCount) {
52 | this.otherGcCount = otherGcCount;
53 | }
54 |
55 | public long getOtherGcTime() {
56 | return otherGcTime;
57 | }
58 |
59 | public void setOtherGcTime(long otherGcTime) {
60 | this.otherGcTime = otherGcTime;
61 | }
62 |
63 | @Override
64 | public String toJsonStr() {
65 | return "{" +
66 | "\"minorGcCount\":\"" + minorGcCount +
67 | "\", \"minorGcTimeMS\":\"" + minorGcTime +
68 | "\", \"fullGcCount\":\"" + fullGcCount +
69 | "\", \"fullGcTimeMS\":\"" + fullGcTime +
70 | "\", \"otherGcCount\":\"" + otherGcCount +
71 | "\", \"otherGcTime\":\"" + otherGcTime +
72 | "\"}";
73 | }
74 |
75 | @Override
76 | public String toString() {
77 | return "\nGCStats{" +
78 | "\n\tminorGcCount=" + minorGcCount +
79 | ",\n\tminorGcTime=" + minorGcTime +
80 | ",\n\tfullGcCount=" + fullGcCount +
81 | ",\n\tfullGcTime=" + fullGcTime +
82 | ",\n\totherGcCount=" + otherGcCount +
83 | ",\n\totherGcTime=" + otherGcTime +
84 | "\n}";
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/s2g-zuul-core/src/main/java/io/spring2go/tools/common/LogHandler.java:
--------------------------------------------------------------------------------
1 | package io.spring2go.tools.common;
2 |
3 | import org.slf4j.Logger;
4 | import org.slf4j.LoggerFactory;
5 |
6 |
7 | public class LogHandler implements StatsHandler {
8 | private Logger logger = LoggerFactory.getLogger(this.getClass());
9 |
10 | @Override
11 | public void process(Stats stats) {
12 | logger.info(stats.toString());
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/s2g-zuul-core/src/main/java/io/spring2go/tools/common/MemoryStats.java:
--------------------------------------------------------------------------------
1 | package io.spring2go.tools.common;
2 |
3 | import io.spring2go.tools.util.ByteUtil;
4 |
5 | public class MemoryStats implements Stats {
6 | private long heapUsedMemory;
7 | private long heapCommitedMemory;
8 | private long heapMaxMemory;
9 |
10 | private long nonHeapUsedMemory;
11 | private long nonHeapCommitedMemory;
12 | private long nonHeapMaxMemory;
13 |
14 | public long getHeapUsedMemory() {
15 | return heapUsedMemory;
16 | }
17 |
18 | public void setHeapUsedMemory(long heapUsedMemory) {
19 | this.heapUsedMemory = heapUsedMemory;
20 | }
21 |
22 | public long getHeapCommitedMemory() {
23 | return heapCommitedMemory;
24 | }
25 |
26 | public void setHeapCommitedMemory(long heapCommitedMemory) {
27 | this.heapCommitedMemory = heapCommitedMemory;
28 | }
29 |
30 | public long getHeapMaxMemory() {
31 | return heapMaxMemory;
32 | }
33 |
34 | public void setHeapMaxMemory(long heapMaxMemory) {
35 | this.heapMaxMemory = heapMaxMemory;
36 | }
37 |
38 | public long getNonHeapUsedMemory() {
39 | return nonHeapUsedMemory;
40 | }
41 |
42 | public void setNonHeapUsedMemory(long nonHeapUsedMemory) {
43 | this.nonHeapUsedMemory = nonHeapUsedMemory;
44 | }
45 |
46 | public long getNonHeapCommitedMemory() {
47 | return nonHeapCommitedMemory;
48 | }
49 |
50 | public void setNonHeapCommitedMemory(long nonHeapCommitedMemory) {
51 | this.nonHeapCommitedMemory = nonHeapCommitedMemory;
52 | }
53 |
54 | public long getNonHeapMaxMemory() {
55 | return nonHeapMaxMemory;
56 | }
57 |
58 | public void setNonHeapMaxMemory(long nonHeapMaxMemory) {
59 | this.nonHeapMaxMemory = nonHeapMaxMemory;
60 | }
61 |
62 | @Override
63 | public String toJsonStr() {
64 | return "{" +
65 | "\"heapUsedMemory\":\"" + ByteUtil.bytesToSize(heapUsedMemory) +
66 | "\", \"heapCommitedMemory\":\"" + ByteUtil.bytesToSize(heapCommitedMemory) +
67 | "\", \"heapMaxMemory\":\"" + ByteUtil.bytesToSize(heapMaxMemory) +
68 | "\", \"nonHeapUsedMemory\":\"" + ByteUtil.bytesToSize(nonHeapUsedMemory) +
69 | "\", \"nonHeapCommitedMemory\":\"" + ByteUtil.bytesToSize(nonHeapCommitedMemory) +
70 | "\", \"nonHeapMaxMemory\":\"" + ByteUtil.bytesToSize(nonHeapMaxMemory) +
71 | "\"}";
72 | }
73 |
74 | @Override
75 | public String toString() {
76 | return "\nMemoryStats{" +
77 | "\n\theapUsedMemory=" + ByteUtil.bytesToSize(heapUsedMemory) +
78 | ", \n\theapCommitedMemory=" + ByteUtil.bytesToSize(heapCommitedMemory) +
79 | ", \n\theapMaxMemory=" + ByteUtil.bytesToSize(heapMaxMemory) +
80 | ", \n\tnonHeapUsedMemory=" + ByteUtil.bytesToSize(nonHeapUsedMemory) +
81 | ", \n\tnonHeapCommitedMemory=" + ByteUtil.bytesToSize(nonHeapCommitedMemory) +
82 | ", \n\tnonHeapMaxMemory=" + ByteUtil.bytesToSize(nonHeapMaxMemory) +
83 | "\n}";
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/s2g-zuul-core/src/main/java/io/spring2go/tools/common/Stats.java:
--------------------------------------------------------------------------------
1 | package io.spring2go.tools.common;
2 |
3 |
4 | public interface Stats {
5 | String toJsonStr();
6 | }
7 |
--------------------------------------------------------------------------------
/s2g-zuul-core/src/main/java/io/spring2go/tools/common/StatsGetter.java:
--------------------------------------------------------------------------------
1 | package io.spring2go.tools.common;
2 |
3 |
4 | public interface StatsGetter {
5 |
6 | Stats get();
7 | }
8 |
--------------------------------------------------------------------------------
/s2g-zuul-core/src/main/java/io/spring2go/tools/common/StatsHandler.java:
--------------------------------------------------------------------------------
1 | package io.spring2go.tools.common;
2 |
3 |
4 | public interface StatsHandler {
5 | void process(Stats stats);
6 | }
7 |
--------------------------------------------------------------------------------
/s2g-zuul-core/src/main/java/io/spring2go/tools/common/StatusInfo.java:
--------------------------------------------------------------------------------
1 | package io.spring2go.tools.common;
2 |
3 | public class StatusInfo extends AbstractHandler{
4 | volatile GCStats gcStats = new GCStats();
5 | volatile MemoryStats memoryStats = new MemoryStats();
6 | volatile ThreadStats threadStats = new ThreadStats();
7 | volatile ClassStats classStats = new ClassStats();
8 | volatile OperatingSystemStats systemStats = new OperatingSystemStats();
9 |
10 | public GCStats getGCStats(){
11 | return this.gcStats;
12 | }
13 |
14 | @Override
15 | protected void processGCStats(GCStats gcStats) {
16 | this.gcStats = gcStats;
17 | }
18 |
19 | @Override
20 | protected void processMemoryStats(MemoryStats memoryStats) {
21 | this.memoryStats = memoryStats;
22 | }
23 |
24 | @Override
25 | protected void processThreadStats(ThreadStats threadStats) {
26 | this.threadStats = threadStats;
27 | }
28 |
29 | @Override
30 | protected void processClassStats(ClassStats classStats) {
31 | this.classStats = classStats;
32 | }
33 |
34 | @Override
35 | protected void processOperatingSystemStats(OperatingSystemStats operatingSystemStats) {
36 | this.systemStats = operatingSystemStats;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/s2g-zuul-core/src/main/java/io/spring2go/tools/common/ThreadStats.java:
--------------------------------------------------------------------------------
1 | package io.spring2go.tools.common;
2 |
3 | public class ThreadStats implements Stats {
4 | //Include daemon and none-daemon
5 | private int currentThreadCount;
6 |
7 | private int daemonThreadCount;
8 |
9 | private long beenCreatedThreadCount;
10 |
11 | public int getCurrentThreadCount() {
12 | return currentThreadCount;
13 | }
14 |
15 | public void setCurrentThreadCount(int currentThreadCount) {
16 | this.currentThreadCount = currentThreadCount;
17 | }
18 |
19 | public int getDaemonThreadCount() {
20 | return daemonThreadCount;
21 | }
22 |
23 | public void setDaemonThreadCount(int daemonThreadCount) {
24 | this.daemonThreadCount = daemonThreadCount;
25 | }
26 |
27 | public long getBeenCreatedThreadCount() {
28 | return beenCreatedThreadCount;
29 | }
30 |
31 | public void setBeenCreatedThreadCount(long beenCreatedThreadCount) {
32 | this.beenCreatedThreadCount = beenCreatedThreadCount;
33 | }
34 |
35 | @Override
36 | public String toJsonStr() {
37 | return "{" +
38 | "\"currentThreadCount\":\"" + currentThreadCount +
39 | "\", \"daemonThreadCount\":\"" + daemonThreadCount +
40 | "\", \"beenCreatedThreadCount\":\"" + beenCreatedThreadCount +
41 | "\"}";
42 | }
43 |
44 | @Override
45 | public String toString() {
46 | return "\nThreadStats{" +
47 | "\t\ncurrentThreadCount=" + currentThreadCount +
48 | ", \t\ndaemonThreadCount=" + daemonThreadCount +
49 | ", \t\nbeenCreatedThreadCount=" + beenCreatedThreadCount +
50 | "\n}";
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/s2g-zuul-core/src/main/java/io/spring2go/tools/servlet/EnvServlet.java:
--------------------------------------------------------------------------------
1 | package io.spring2go.tools.servlet;
2 |
3 | import java.io.IOException;
4 | import java.io.PrintWriter;
5 | import java.util.Map;
6 | import java.util.TreeMap;
7 |
8 | import javax.servlet.ServletException;
9 | import javax.servlet.http.HttpServlet;
10 | import javax.servlet.http.HttpServletRequest;
11 | import javax.servlet.http.HttpServletResponse;
12 |
13 | import org.eclipse.jetty.server.Response;
14 |
15 | import com.alibaba.fastjson.JSON;
16 |
17 | public class EnvServlet extends HttpServlet{
18 |
19 | @Override
20 | protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
21 |
22 | // make a writable copy of the immutable System.getenv() map
23 | Map envVarsMap = new TreeMap(System.getenv());
24 |
25 | String jsonStr = JSON.toJSONString(envVarsMap);
26 |
27 | resp.addHeader("Access-Control-Allow-Origin", "*");
28 | resp.addHeader("Access-Control-Allow-Headers","Content-Type, Accept");
29 | resp.setContentType("application/json; charset=UTF-8");
30 |
31 | PrintWriter writer = resp.getWriter();
32 | try{
33 | writer.write(jsonStr);
34 | resp.setStatus(Response.SC_OK);
35 | } finally {
36 | if (writer != null) {
37 | writer.close();
38 | }
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/s2g-zuul-core/src/main/java/io/spring2go/tools/servlet/HystrixServlet.java:
--------------------------------------------------------------------------------
1 | package io.spring2go.tools.servlet;
2 |
3 | import java.io.IOException;
4 | import java.io.PrintWriter;
5 | import java.util.Map;
6 | import java.util.TreeMap;
7 |
8 | import javax.servlet.ServletException;
9 | import javax.servlet.http.HttpServlet;
10 | import javax.servlet.http.HttpServletRequest;
11 | import javax.servlet.http.HttpServletResponse;
12 |
13 | import org.eclipse.jetty.server.Response;
14 |
15 | import com.alibaba.fastjson.JSON;
16 | import com.netflix.config.DynamicPropertyFactory;
17 | import com.netflix.hystrix.HystrixCircuitBreaker;
18 | import com.netflix.hystrix.HystrixCommandKey;
19 | import com.netflix.hystrix.HystrixCommandMetrics;
20 |
21 | public class HystrixServlet extends HttpServlet {
22 |
23 | @Override
24 | protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
25 | PrintWriter writer = resp.getWriter();
26 | try {
27 |
28 | // make a writable copy of the immutable System.getenv() map
29 | Map breakerMap = new TreeMap();
30 |
31 | for (HystrixCommandMetrics commandMetrics : HystrixCommandMetrics.getInstances()) {
32 | HystrixCommandKey key = commandMetrics.getCommandKey();
33 | HystrixCircuitBreaker circuitBreaker = HystrixCircuitBreaker.Factory.getInstance(key);
34 |
35 | if (circuitBreaker != null) {
36 | if (circuitBreaker.isOpen()) {
37 | breakerMap.put(key.name(), DynamicPropertyFactory.getInstance().getStringProperty("mail."+key.name(), "bobo@spring2go.com").get());
38 | }else{
39 | if(DynamicPropertyFactory.getInstance().getBooleanProperty("hystrix.command."+key.name()+".circuitBreaker.forceOpen",false).get()){
40 | breakerMap.put(key.name(), DynamicPropertyFactory.getInstance().getStringProperty("mail."+key.name(), "bobo@spring2go.com").get());
41 | }else if(DynamicPropertyFactory.getInstance().getBooleanProperty("hystrix.command.default.circuitBreaker.forceOpen",false).get()){
42 | breakerMap.put(key.name(), DynamicPropertyFactory.getInstance().getStringProperty("mail."+key.name(), "bobo@spring2go.com").get());
43 | }
44 | }
45 | }
46 | }
47 |
48 | String jsonStr = JSON.toJSONString(breakerMap);
49 |
50 | resp.addHeader("Access-Control-Allow-Origin", "*");
51 | resp.addHeader("Access-Control-Allow-Headers", "Content-Type, Accept");
52 | resp.setContentType("application/json; charset=UTF-8");
53 |
54 | writer.write(jsonStr);
55 | resp.setStatus(Response.SC_OK);
56 | }catch(Throwable t){
57 | writer.write(t.getMessage());
58 | resp.setStatus(Response.SC_INTERNAL_SERVER_ERROR);
59 | }finally {
60 |
61 | if (writer != null) {
62 | writer.close();
63 | }
64 | }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/s2g-zuul-core/src/main/java/io/spring2go/tools/servlet/PropsServlet.java:
--------------------------------------------------------------------------------
1 | package io.spring2go.tools.servlet;
2 |
3 | import java.io.IOException;
4 | import java.io.PrintWriter;
5 | import java.util.Iterator;
6 | import java.util.Map;
7 | import java.util.TreeMap;
8 |
9 | import javax.servlet.ServletException;
10 | import javax.servlet.http.HttpServlet;
11 | import javax.servlet.http.HttpServletRequest;
12 | import javax.servlet.http.HttpServletResponse;
13 |
14 | import org.apache.commons.configuration.AbstractConfiguration;
15 | import org.codehaus.jackson.map.ObjectMapper;
16 | import org.eclipse.jetty.server.Response;
17 |
18 | import com.alibaba.fastjson.JSON;
19 | import com.netflix.config.ConfigurationManager;
20 |
21 | public class PropsServlet extends HttpServlet {
22 |
23 | private ObjectMapper mapper = new ObjectMapper();
24 |
25 | @Override
26 | protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
27 | Map allPropsAsString = new TreeMap();
28 | AbstractConfiguration config = ConfigurationManager.getConfigInstance();
29 | Iterator keys = config.getKeys();
30 |
31 | while (keys.hasNext()) {
32 | final String key = keys.next();
33 | final Object value;
34 | value = config.getProperty(key);
35 | allPropsAsString.put(key, value.toString());
36 | }
37 |
38 | String jsonStr = JSON.toJSONString(allPropsAsString);
39 | //mapper.writeValueAsString(allPropsAsString);
40 |
41 | resp.addHeader("Access-Control-Allow-Origin", "*");
42 | resp.addHeader("Access-Control-Allow-Headers","Content-Type, Accept");
43 | resp.setContentType("application/json; charset=UTF-8");
44 |
45 | PrintWriter writer = resp.getWriter();
46 | try{
47 | writer.write(jsonStr);
48 | resp.setStatus(Response.SC_OK);
49 | } finally {
50 | if (writer != null) {
51 | writer.close();
52 | }
53 | }
54 | }
55 | }
--------------------------------------------------------------------------------
/s2g-zuul-core/src/main/java/io/spring2go/tools/servlet/StaticServlet.java:
--------------------------------------------------------------------------------
1 | package io.spring2go.tools.servlet;
2 |
3 | import java.io.ByteArrayOutputStream;
4 | import java.io.IOException;
5 | import java.io.InputStream;
6 | import java.util.HashMap;
7 | import java.util.Map;
8 | import java.util.concurrent.ConcurrentHashMap;
9 |
10 | import javax.servlet.ServletException;
11 | import javax.servlet.http.HttpServlet;
12 | import javax.servlet.http.HttpServletRequest;
13 | import javax.servlet.http.HttpServletResponse;
14 |
15 | import org.eclipse.jetty.server.Response;
16 | import org.slf4j.Logger;
17 | import org.slf4j.LoggerFactory;
18 |
19 | public class StaticServlet extends HttpServlet {
20 |
21 | final static Map EXT_TO_MEDIATYPE = new HashMap();
22 | static {
23 | EXT_TO_MEDIATYPE.put("js", "text/javascript");
24 | EXT_TO_MEDIATYPE.put("png", "image/png");
25 | EXT_TO_MEDIATYPE.put("gif", "image/gif");
26 | EXT_TO_MEDIATYPE.put("css", "text/css");
27 | EXT_TO_MEDIATYPE.put("jpg", "image/jpeg");
28 | EXT_TO_MEDIATYPE.put("jpeg", "image/jpeg");
29 | EXT_TO_MEDIATYPE.put("html", "text/html");
30 | }
31 |
32 | final static ConcurrentHashMap CONTENT_CACHE = new ConcurrentHashMap();
33 |
34 | Logger logger = LoggerFactory.getLogger(this.getClass());
35 |
36 | @Override
37 | protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
38 | String path = req.getRequestURI();
39 | if(path.equals("/")){
40 | path = "/index.html";
41 | }
42 | String ext = path.substring(path.lastIndexOf(".")+1);
43 | String mediaType = EXT_TO_MEDIATYPE.get(ext);
44 | byte[] contentBytes = null;
45 |
46 | if(mediaType!=null){
47 | contentBytes = CONTENT_CACHE.get(path);
48 | if (contentBytes == null) {
49 | InputStream is = getClass().getClassLoader().getResourceAsStream("content" + path);
50 | if (is != null) {
51 | try {
52 | ByteArrayOutputStream os = new ByteArrayOutputStream(4096);
53 | byte[] bs = new byte[4096];
54 | int c = 0;
55 | while((c = is.read(bs)) > 0){
56 | os.write(bs,0,c);
57 | }
58 | contentBytes=os.toByteArray();
59 | CONTENT_CACHE.putIfAbsent(path, contentBytes);
60 | } catch (IOException e) {
61 | try {
62 | is.close();
63 | } catch (IOException e1) {
64 | logger.warn("Could not close the resource " + path, e1);
65 | }
66 | }
67 | }
68 |
69 | }
70 | }
71 |
72 | if (contentBytes == null) {
73 | resp.sendError(Response.SC_NOT_FOUND);
74 | }else {
75 |
76 | resp.addHeader("Access-Control-Allow-Origin", "*");
77 | resp.addHeader("Access-Control-Allow-Headers","Content-Type, Accept");
78 | resp.setContentType(mediaType);
79 | resp.setStatus(Response.SC_OK);
80 | resp.getOutputStream().write(contentBytes);
81 | resp.getOutputStream().close();
82 | }
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/s2g-zuul-core/src/main/java/io/spring2go/tools/servlet/StatusServlet.java:
--------------------------------------------------------------------------------
1 | package io.spring2go.tools.servlet;
2 |
3 | import java.io.IOException;
4 | import java.io.PrintWriter;
5 | import java.lang.management.ManagementFactory;
6 | import java.lang.management.RuntimeMXBean;
7 | import java.text.SimpleDateFormat;
8 | import java.util.Date;
9 | import java.util.LinkedHashMap;
10 | import java.util.Map;
11 |
12 | import javax.servlet.ServletException;
13 | import javax.servlet.http.HttpServlet;
14 | import javax.servlet.http.HttpServletRequest;
15 | import javax.servlet.http.HttpServletResponse;
16 |
17 | import org.eclipse.jetty.server.Response;
18 |
19 | import com.alibaba.fastjson.JSON;
20 |
21 | import io.spring2go.tools.common.StatusInfo;
22 | import io.spring2go.tools.stat.ClassStatsGetter;
23 | import io.spring2go.tools.stat.MemoryStatsGetter;
24 | import io.spring2go.tools.stat.OperatingSystemStatsGetter;
25 | import io.spring2go.tools.stat.ThreadStatsGetter;
26 | import io.spring2go.tools.util.TimeUtil;
27 |
28 | public class StatusServlet extends HttpServlet {
29 |
30 | private StatusInfo statusInfo;
31 |
32 | private ClassStatsGetter classStatsGetter;
33 | private ThreadStatsGetter threadStatsGetter;
34 | private MemoryStatsGetter memoryStatsGetter;
35 | private OperatingSystemStatsGetter operatingSystemStatsGetter;
36 |
37 | RuntimeMXBean rb = ManagementFactory.getRuntimeMXBean();
38 |
39 | public StatusServlet(StatusInfo statusInfo) {
40 | this.statusInfo = statusInfo;
41 | this.classStatsGetter = new ClassStatsGetter();
42 | this.threadStatsGetter = new ThreadStatsGetter();
43 | this.memoryStatsGetter = new MemoryStatsGetter();
44 | this.operatingSystemStatsGetter = new OperatingSystemStatsGetter();
45 | }
46 |
47 | @Override
48 | protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
49 |
50 | Map props = new LinkedHashMap();
51 |
52 | props.put("Server Start Time", new SimpleDateFormat("yyyy-MM-dd HH:ss").format(new Date(rb.getStartTime())));
53 | props.put("Server Up Time", TimeUtil.readableTimeInterval(rb.getUptime()));
54 |
55 | addJsonContent(props, "System ", operatingSystemStatsGetter.get().toJsonStr());
56 | addJsonContent(props, "Memory ", memoryStatsGetter.get().toJsonStr());
57 | addJsonContent(props, "Thread ", threadStatsGetter.get().toJsonStr());
58 | addJsonContent(props, "Class ", classStatsGetter.get().toJsonStr());
59 | addJsonContent(props, "GC(last Minute) ", statusInfo.getGCStats().toJsonStr());
60 |
61 | String jsonStr = JSON.toJSONString(props);
62 |
63 | resp.addHeader("Access-Control-Allow-Origin", "*");
64 | resp.addHeader("Access-Control-Allow-Headers","Content-Type, Accept");
65 | resp.setContentType("application/json; charset=UTF-8");
66 |
67 | PrintWriter writer = resp.getWriter();
68 | try{
69 | writer.write(jsonStr);
70 | resp.setStatus(Response.SC_OK);
71 | } finally {
72 | if (writer != null) {
73 | writer.close();
74 | }
75 | }
76 | }
77 |
78 | private void addJsonContent(Map props, String prefix, String jsonContent) throws IOException {
79 | Map