精华内容
下载资源
问答
  • Tomcat扩展——监控

    千次阅读 2015-07-04 13:29:34
    最近心血来潮,想是否可以通过增加一个tomcat的扩展,来持续收集tomcat服务器本身的性能信息,如线程池的各项数据,请求数等等,这样可以配合业务方面的监控,可以更方便的分析调整tomcat配置,以提供更好的服务。...


    (转过来,源地址:http://www.jmatrix.org/notes/1067.html)


    最近心血来潮,想是否可以通过增加一个tomcat的扩展,来持续收集tomcat服务器本身的性能信息,如线程池的各项数据,请求数等等,这样可以配合业务方面的监控,可以更方便的分析调整tomcat配置,以提供更好的服务。

     

    这样也不需要每次通过连接jmx去观察数据,而且idc环境要开启jmx,还得涉及各种安全问题…….

     

    Tomcat manager中StatusManagerServlet就是通过JMX提供了Tomcat服务的当前状态信息。我也会“抄袭”这里的代码来收集服务器数据。

     

    要想定时的收集Tomcat的数据,需要在tomcat启动过程中,启一个定时任务去不停的收集服务信息,之后根据自己的需要,看是通过写日志方式保存,还是上报,抑或其它方式。

     

    要做到不侵入tomcat本身源码,可以选择通过Listener的方式,实现一个自定义Listener,监听服务启动事件,启动数据采集任务,定时收集数据,如:

    public class ServerInfoMonitorLifecycleListener implementsLifecycleListener {
    
          private ServerInfoCollection collect = new ServerInfoCollection();
    
          @Override
          public void lifecycleEvent(LifecycleEvent event ) {
              Lifecycle lifecycle = event .getLifecycle();
               if (Lifecycle.AFTER_START_EVENT .equals(event .getType())
                       && lifecycle instanceof Server) {
                   collect.startMonitor();
              }
               if (Lifecycle.BEFORE_STOP_EVENT .equals(event .getType())
                       && lifecycle instanceof Server) {
                   collect.stopMonitor();
              }
         }
    }

    这里监控的是Server的启动事件,需要注意,如果你想监控其它container,如host,context等,则配置listener的时候需要放到对应的container,大多数情况下,我们还是习惯配置在Server这一级别,确实在Server这一级别是最方便的。Tomcat本身的个别listener,想监听host,context等的事件是通过监听到Server事件的时候依次对server下面的host,context等添加listener。

     

    有了定时收集tomcat数据的定时任务,下面就是数据的收集了。

     

    首先得先获取需要的Mbean,如:

    // Retrieve the MBean server
               mBeanServer = Registry.getRegistry( null , null ).getMBeanServer();
    
               try {
                   // Query Thread Pools
                   threadPools .clear();
                  String onStr = "*:type=ThreadPool,*" ;
                  ObjectName objectName = new ObjectName(onStr );
                  Set set = mBeanServer .queryMBeans( objectName, null );
                  Iterator iterator = set .iterator();
                   while (iterator .hasNext()) {
                       ObjectInstance oi = iterator.next();
                        threadPools .addElement(oi .getObjectName());
                  }
    
                   // Query Global Request Processors
                   globalRequestProcessors .clear();
                   onStr = "*:type=GlobalRequestProcessor,*" ;
                   objectName = new ObjectName( onStr);
                   set = mBeanServer .queryMBeans(objectName , null );
                   iterator = set.iterator();
                   while (iterator .hasNext()) {
                       ObjectInstance oi = iterator.next();
                        globalRequestProcessors .addElement(oi .getObjectName());
                  }
    
              } catch (Exception e ) {
                   log.error( "init failed." , e );
              }

    通过Mbean获取tomcat性能数据:

    Enumeration enumeration = threadPools .elements();
                   while (enumeration .hasMoreElements()) {
                       ObjectName objectName = enumeration .nextElement();
                       String name = objectName .getKeyProperty("name" );
    
                       ServerInfo serverInfo = new ServerInfo();
                        serverInfo .setMaxThreads((Integer) mBeanServer .getAttribute(
                                  objectName , "maxThreads" ));
                        serverInfo .setCurrentThreadCount((Integer) mBeanServer
                                 .getAttribute( objectName ,"currentThreadCount" ));
                        serverInfo .setCurrentThreadsBusy((Integer) mBeanServer
                                 .getAttribute( objectName ,"currentThreadsBusy" ));
                        try {
                            Object value = mBeanServer .getAttribute(objectName ,
                                       "keepAliveCount" );
                             serverInfo .setKeepAliveCount((Integer) value );
                       } catch (Exception e ) {
                             // Ignore
                       }
    
                       ObjectName grpName = null ;
                       Enumeration reqEnumer =globalRequestProcessors
                                 .elements();
                        while (reqEnumer .hasMoreElements()) {
                            ObjectName reqObjName = reqEnumer .nextElement();
                             if (name .equals(reqObjName .getKeyProperty( "name"))) {
                                  grpName = reqObjName ;
                            }
                       }
    
                        if (grpName == null) {
                             return ;
                       }
    
                        serverInfo .setMaxTime((Long) mBeanServer .getAttribute(grpName ,
                                  "maxTime" ));
                        serverInfo .setProcessingTime((Long) mBeanServer .getAttribute(
                                  grpName, "processingTime" ));
                        serverInfo .setRequestCount((Integer) mBeanServer .getAttribute(
                                  grpName, "requestCount" ));
                        serverInfo .setErrorCount((Integer) mBeanServer .getAttribute(
                                  grpName, "errorCount" ));
                        serverInfo .setBytesReceived((Long) mBeanServer .getAttribute(
                                  grpName, "bytesReceived" ));
                        serverInfo .setBytesSent((Long) mBeanServer .getAttribute(
                                  grpName, "bytesSent" ));
    
                        store.storeInfo( serverInfo );
    
                  }

    在server.xml配置好自定义的listener,启动tomcat,便可以看到收集到的数据,如(这里为了测试,收集到的数据直接写日志):

    ServerInfo:maxThreads:200,currentThreadCount:16,busyThreadCount:6,keepAliveCount:0,maxTime:6166,requestCount:57,errorCount:0,processTime:10380,bytesRec:0,bytesSend:238874

    当然,还有很多其它的信息可以收集,看具体需要。

     

    另外,还可以借助Value链条,编写自己的Value来上报请求处理时间,异常情况等等。

     

    基础的代码可在github上看看:https://github.com/jjmatrix/tomcat-extension


    相关的内容:

    Tomcat源码走读1:从何开始

    Tomcat源码走读2:启动过程

    Tomcat源码走读5:请求处理

    Tomcat源码走读——内存泄露检测






    展开全文
  • 模仿tomcat---初识感受

    2019-01-14 00:25:30
    前言 很早就有看到公众号推送的...封装请求参数信息,其中包括地址映射的servlet,请求地址,请求端口等 执行请求封装返回信息等 主要代码实现 项目地址:抄袭miniTomcat 使用Socket做网络连接端口监听,这里一定要...

    前言

    很早就有看到公众号推送的手写简单tomcat的类似文章。一直想模仿着写写,主要感受下人家的思维和思路,今天终于参考别人写的自己手动也写了一下。

    整体思路要求

    1. 保证长连接,保持长时间监控端口请求
    2. 封装请求参数信息,其中包括地址映射的servlet,请求地址,请求端口等
    3. 执行请求封装返回信息等

    主要代码实现

    项目地址:抄袭miniTomcat

    1. 使用Socket做网络连接端口监听,这里一定要注意异常catch掉,否则会断掉服务
    /**
         * 启动类
         */
        public void start() {
            ServerSocket serverSocket = null;
            try {
                serverSocket = new ServerSocket(PORT);
                //while保持长时间连接
                while (true) {
                    //注意这里try catch保证catch到所有错误保证程序不停止
                    try {
                        Socket accept = serverSocket.accept();
                        InputStream inputStream = accept.getInputStream();
                        OutputStream outputStream = accept.getOutputStream();
                        Request request = Request.create(inputStream);
                        Response response = Response.create(outputStream);
                        requestMapping.dispatch(request, response);
                        accept.close();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                //保证连接关闭
                if (Objects.nonNull(serverSocket)) {
                    try {
                        serverSocket.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    
    1. Request封装:analysis方法是主要的解析方法,httpString拿到的字符串就是http请求的request的一整块,通过换行符和空格去拿到对应的需要封装的参数,包括请求参数等(这里只拿了url和请求方式),具体http请求有的参数参考http官方文档
    package http;
    
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.Objects;
    
    /**
     * request封装类
     *
     * @author 50238
     */
    public class Request {
    
        static Request create(InputStream inputStream) {
            return new Request(inputStream);
        }
    
        /**
         * http
         */
        private String httpString;
    
        /**
         * 请求方式
         */
        private String method;
    
        /**
         * 请求地址
         */
        private String url;
    
    
        private Request(InputStream inputStream) {
            if (Objects.isNull(inputStream)) {
                throw new NullPointerException("http请求输入错误");
            }
            try {
                byte[] inputByte = new byte[1024];
                inputStream.read(inputByte);
                httpString = new String(inputByte);
                analysis();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        /**
         * 解析http
         * 主要根据http协议进行解析:header body参数等
         * 这里有一定感觉所谓的协议,不过是按照规矩组成的字符串
         * {参考http协议官方文档@link: https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Messages}
         */
        private void analysis() {
            String[] split = httpString.split("\\n");
            System.out.println(httpString);
            this.method = split[0].split("\\s")[0];
            this.url = split[0].split("\\s")[1];
        }
    
        public String getMethod() {
            return method;
        }
    
        public void setMethod(String method) {
            this.method = method;
        }
    
        public String getUrl() {
            return url;
        }
    
        public void setUrl(String url) {
            this.url = url;
        }
    }
    
    
    1. Response封装:这里主要是返回数据封装,即http请求中的Response那一块数据(我这里只返回了一个html字符,Content-type指定返回类型)
    package http;
    
    import java.io.IOException;
    import java.io.OutputStream;
    
    /**
     * 输出
     *
     * @author 50238
     */
    public class Response {
        private OutputStream outputStream;
    
        static Response create(OutputStream outputStream) {
            return new Response(outputStream);
        }
    
        private Response(OutputStream outputStream) {
            this.outputStream = outputStream;
        }
    
        /**
         * 输出内容
         * 这里指定协议,数据类型,返回数据等
         *
         * @param outString
         */
        public void write(String outString) throws IOException {
            String httpResponse = "HTTP/1.1 200 OK\n" +
                    "Content-type: text/html\n" +
                    "\r\n" +
                    "<html><body>" +
                    outString +
                    "</body></html>";
            outputStream.write(httpResponse.getBytes());
            outputStream.close();
        }
    }
    
    
    1. servlet定义:MyServlet抽象类定义了通用的get post调用方法,analysis做请求方式的解析调用
    package http;
    
    /**
     * 自定义servlet
     *
     * @author 50238
     */
    abstract class MyServlet {
        /**
         * get method
         *
         * @param request
         * @param response
         */
        abstract void doGet(Request request, Response response);
    
        /**
         * post method
         *
         * @param request
         * @param response
         */
        abstract void doPost(Request request, Response response);
    
        /**
         * 解析请求方式
         * 这里可以进行解析其他请求方式post get put delete等
         * {参考官方文档@link:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Methods/DELETE}
         *
         * @param request
         * @param response
         */
        void analysis(Request request, Response response) {
            String method = request.getMethod().toUpperCase();
            switch (method) {
                case "GET":
                    doGet(request, response);
                    break;
                case "POST":
                    doPost(request, response);
                    break;
                default:
                    throw new NullPointerException("请求方法不支持");
            }
        }
    }
    
    
    package http;
    
    import java.io.IOException;
    
    /**
     * 自定义Servlet
     *
     * @author 50238
     */
    public class Servlet extends MyServlet {
    
        @Override
        void doGet(Request request, Response response) {
            try {
                response.write("doGet");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        @Override
        void doPost(Request request, Response response) {
            try {
                response.write("doPost");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    
    
    1. 最后地址映射方法(这里只写了一个hello的映射),主要方法init初始化servlet。
    package http;
    
    import java.util.HashMap;
    
    /**
     * 地址映射
     *
     * @author 50238
     */
    public class RequestMapping {
        /**
         * 地址解析
         * {key:地址,类名}
         */
        private final HashMap<String, String> SERVLET_URL = new HashMap<>(1);
    
        /**
         * 地址解析
         * {key:地址,实例}
         */
        private final HashMap<String, MyServlet> SERVLETS = new HashMap<>(1);
    
        {
            //这里提前指定了地址和servlet,等于tomcat解析web.xml
            //这里可以写成注解扫描处理servlet或者解析xml处理,后面有时间写一个吧
            SERVLET_URL.put("/hello", "http.Servlet");
            init();
        }
    
        /**
         * 初始化
         * 通过反射实例化servlet
         */
        private void init() {
            SERVLET_URL.forEach((k, v) -> {
                try {
                    try {
                        SERVLETS.put(k, (MyServlet) Class.forName(v).newInstance());
                    } catch (InstantiationException | IllegalAccessException e) {
                        e.printStackTrace();
                    }
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                }
            });
        }
    
        /**
         * 获取servlet
         *
         * @return
         */
        public void dispatch(Request request, Response response) {
            String url = request.getUrl();
            MyServlet myServlet = SERVLETS.get(url);
            myServlet.analysis(request, response);
        }
    
    }
    
    
    1. 启动
    import http.MyTomcat;
    
    /**
     * 启动类
     *
     * @author 50238
     */
    public class Application {
    
    
        public static void main(String[] args) {
            MyTomcat m = new MyTomcat();
            m.start();
        }
    }
    
    

    RequestMapping类扩展想法思路:

    上面地址解析时写死的,只能请求http//xxxxxxx/hello,如果想丰富的话有两种常用处理方式:

    1. 注解式:通过扫描包将自定义注解@Servlet(可以自己命名)扫描放到容器中,获取必填参数url进行Map(url,servlet)映射
    2. 配置xml方式,解析xml按照格式解析和注解方式一样放入容器

    如果想配置过滤器也可以使用servlet相同方式进行处理,放入容器然后地址映射在servlet之前调用即可

    个人总结

    Http协议:从这个项目中个人感觉所谓的协议就是一串规定格式的串罢了,其实也不是感觉很神秘了。不过看官方文档可以知道很多http可以优化的东西,这里不赘述,作为web开发还是应该知道这些。

    Socket:感受到了自己对网络编程这块的缺失,对Socket不熟悉。里面还涉及着大量的东西。

    IO:,以前也总是感觉没啥用。在何时起感觉到程序无论什么操作感觉都是在处理IO,让我认识到了IO的重要性。在学习Mysql时很多时候也提到IO对优化的影响,这也是一大片空白需要恶补。

    反射:很重要的东西,不管是现在主流的框架或者说tonmcat都是用到了这一特性,也是需要注意学习的。

    容器:听着很高大上,可以就理解成一个集合或者Map吧,感觉是一种思想,在之前看Spring、Mybatis的一些东西的时候慢慢的给了我越来越深的印象。

    缺失的东西:这个简单的tomcat还没涉及到多线程的请求、session问题、多项目包共享问题、监听器实现、很多参数解析等问题,感觉任重而道远还要学习的东西很多。

    展开全文
  • instance) URL 按频率(10秒,20秒...) 发起请求并记录响应的信息(连接耗时,是否连接成功,是否有异常), 若检测到不正常(响应码不是200,抛出异常...)时则发送邮件给指定的地址,当检测恢复正常时也发送...

    HeartBeat

    心跳检测应用服务器(如Tomcat,Jetty)的JAVA WEB应用程序.

    如何实现?

    使用HttpClient对指定的服务器(application-instance) URL 按频率(10秒,20秒...) 发起请求并记录响应的信息(连接耗时,是否连接成功,是否有异常),     若检测到不正常(响应码不是200,抛出异常...)时则发送邮件给指定的地址,当检测恢复正常时也发送提醒邮件.

    将来会添加更多的实时提醒方式接口,如微信,短信

    框架及版本Spring Framework - 3.2.2.RELEASE

    Quartz - 2.2.1

    Hibernate - 4.1.7.Final

    Flat UI

    Maven - 3.1.0

    运行环境JRE 1.7 +

    MySql 5.5 +

    Tomcat 7 +

    如何使用?项目是Maven管理的, 需要在电脑上安装maven(开发用的版本号为3.1.0), MySql(开发用的版本号为5.5)

    下载(或clone)项目到本地

    创建MySQL数据库(默认数据库名:heart_beat), 并运行相应的SQL脚本(脚本文件位于others/database目录),

    运行脚本的顺序: HeartBeat.ddl -> quartz_mysql_innodb.sql

    修改HeartBeat.properties(位于src/main/resources目录)中的数据库连接信息(包括username, password等)

    将本地项目导入到IDE(如Intellij IDEA)中,配置Tomcat(或类似的servlet运行服务器), 并启动Tomcat(默认端口为8080)

    另: 也可通过maven package命令将项目编译为war文件(HeartBeat.war),                     将war放在Tomcat中并启动(注意: 这种方式需要将HeartBeat.properties加入到classpath中并正确配置数据库连接信息).

    1d995b7f2882ad1e9c29cc1fb428d147.png

    展开全文
  •  at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1597) [tomcat-embed-core-9.0.41.jar:9.0.41]  at org.apache.tomcat.util.net.SocketProcessorBase.run...
  • java面试题

    2018-04-27 19:55:38
    书写EJB要遵循一定的规范,另外要运行EJB,你需要有相应的EJB容器,比如WebLogic、jboss等,而JavaBean不需要,只需要安装Tomcat就可以了。EJB用于服务端的应用开发,而JavaBean用于客户端应用开发。 触发器? 答:...
  • 实例187 使用过滤器监控网站流量 实例188 防止页面缓存的过滤器 实例189 通过过滤器控制页面输出内容 实例190 使用过滤器自动生成静态页面 实例191 文件上传过滤器 实例192 权限验证过滤器 7.2 监听器的应用 ...
  • 实例187 使用过滤器监控网站流量 实例188 防止页面缓存的过滤器 实例189 通过过滤器控制页面输出内容 实例190 使用过滤器自动生成静态页面 实例191 文件上传过滤器 实例192 权限验证过滤器 7.2 监听器的应用 ...
  •  forward是服务器请求资源,服务器直接访问目标地址的URL,把那个URL的响应内容读取过来,然后把这些内容再发给浏览器,浏览器根本不知道服务器发送的内容是从哪儿来的,所以它的地址栏中还是原来的地址。...
  • java开源包1

    千次下载 热门讨论 2013-06-28 09:14:34
    集中管理请求参数与参数映射 以运行时异常的方式来管理错误的响应 使用泛型来做强类型编程 多协议扩展支持(REST, RPC, SOAP, etc) Rails3消息队列系统 Sidekiq Sidekiq 为 Rails 3 应用程序提供一个高效的消息...
  • java开源包12

    热门讨论 2013-06-28 10:14:45
    集中管理请求参数与参数映射 以运行时异常的方式来管理错误的响应 使用泛型来做强类型编程 多协议扩展支持(REST, RPC, SOAP, etc) Rails3消息队列系统 Sidekiq Sidekiq 为 Rails 3 应用程序提供一个高效的消息...
  • Java资源包01

    2016-08-31 09:16:25
    集中管理请求参数与参数映射 以运行时异常的方式来管理错误的响应 使用泛型来做强类型编程 多协议扩展支持(REST, RPC, SOAP, etc) Rails3消息队列系统 Sidekiq Sidekiq 为 Rails 3 应用程序提供一个高效的消息...
  • 《SpringMVC源码分析:POST请求中的文件处理》 《下载Spring4.1.x源码并用IntelliJ IDEA打开》 《windows下修改、编译、构建spring-framework4.1.8.RELEASE源码》 《spring4.1.8初始化源码学习三部曲之一:...
  • java开源包101

    2016-07-13 10:11:08
    集中管理请求参数与参数映射 以运行时异常的方式来管理错误的响应 使用泛型来做强类型编程 多协议扩展支持(REST, RPC, SOAP, etc) Rails3消息队列系统 Sidekiq Sidekiq 为 Rails 3 应用程序提供一个高效的消息...
  • java开源包11

    热门讨论 2013-06-28 10:10:38
    集中管理请求参数与参数映射 以运行时异常的方式来管理错误的响应 使用泛型来做强类型编程 多协议扩展支持(REST, RPC, SOAP, etc) Rails3消息队列系统 Sidekiq Sidekiq 为 Rails 3 应用程序提供一个高效的消息...
  • java开源包2

    热门讨论 2013-06-28 09:17:39
    集中管理请求参数与参数映射 以运行时异常的方式来管理错误的响应 使用泛型来做强类型编程 多协议扩展支持(REST, RPC, SOAP, etc) Rails3消息队列系统 Sidekiq Sidekiq 为 Rails 3 应用程序提供一个高效的消息...
  • java开源包3

    热门讨论 2013-06-28 09:20:52
    集中管理请求参数与参数映射 以运行时异常的方式来管理错误的响应 使用泛型来做强类型编程 多协议扩展支持(REST, RPC, SOAP, etc) Rails3消息队列系统 Sidekiq Sidekiq 为 Rails 3 应用程序提供一个高效的消息...
  • java开源包6

    热门讨论 2013-06-28 09:48:32
    集中管理请求参数与参数映射 以运行时异常的方式来管理错误的响应 使用泛型来做强类型编程 多协议扩展支持(REST, RPC, SOAP, etc) Rails3消息队列系统 Sidekiq Sidekiq 为 Rails 3 应用程序提供一个高效的消息...
  • java开源包5

    热门讨论 2013-06-28 09:38:46
    集中管理请求参数与参数映射 以运行时异常的方式来管理错误的响应 使用泛型来做强类型编程 多协议扩展支持(REST, RPC, SOAP, etc) Rails3消息队列系统 Sidekiq Sidekiq 为 Rails 3 应用程序提供一个高效的消息...
  • java开源包10

    热门讨论 2013-06-28 10:06:40
    集中管理请求参数与参数映射 以运行时异常的方式来管理错误的响应 使用泛型来做强类型编程 多协议扩展支持(REST, RPC, SOAP, etc) Rails3消息队列系统 Sidekiq Sidekiq 为 Rails 3 应用程序提供一个高效的消息...
  • java开源包4

    热门讨论 2013-06-28 09:26:54
    集中管理请求参数与参数映射 以运行时异常的方式来管理错误的响应 使用泛型来做强类型编程 多协议扩展支持(REST, RPC, SOAP, etc) Rails3消息队列系统 Sidekiq Sidekiq 为 Rails 3 应用程序提供一个高效的消息...
  • java开源包8

    热门讨论 2013-06-28 09:55:26
    集中管理请求参数与参数映射 以运行时异常的方式来管理错误的响应 使用泛型来做强类型编程 多协议扩展支持(REST, RPC, SOAP, etc) Rails3消息队列系统 Sidekiq Sidekiq 为 Rails 3 应用程序提供一个高效的消息...
  • java开源包9

    热门讨论 2013-06-28 09:58:55
    集中管理请求参数与参数映射 以运行时异常的方式来管理错误的响应 使用泛型来做强类型编程 多协议扩展支持(REST, RPC, SOAP, etc) Rails3消息队列系统 Sidekiq Sidekiq 为 Rails 3 应用程序提供一个高效的消息...
  • java开源包7

    热门讨论 2013-06-28 09:52:16
    集中管理请求参数与参数映射 以运行时异常的方式来管理错误的响应 使用泛型来做强类型编程 多协议扩展支持(REST, RPC, SOAP, etc) Rails3消息队列系统 Sidekiq Sidekiq 为 Rails 3 应用程序提供一个高效的消息...
  • dubbox-2.8.1:主要支持基于嵌入式tomcat的http-remoting,优化了REST客户端性能,在REST中支持限制服务端接纳的最大HTTP连接数等等 dubbox-2.8.2: 支持REST中的HTTP logging,包括HTTP header的字段和HTTP body...
  • 摘要:JAVA源码,媒体网络,山寨QQ,Java聊天程序 Java编写的山寨QQ,多人聊天+用户在线,程序分服务端和客户端,典型C/S结构, 当用户发送第一次请求的时候,验证用户登录,创建一个该qq号和服务器端保持通讯连接得线程...
  • JAVA上百实例源码以及开源项目

    千次下载 热门讨论 2016-01-03 17:37:40
     当用户发送第一次请求的时候,验证用户登录,创建一个该qq号和服务器端保持通讯连接得线程,启动该通讯线程,通讯完毕,关闭Scoket。  QQ客户端登录界面,中部有三个JPanel,有一个叫选项卡窗口管理。还可以更新...
  • 综上:一般情况下,网关一般都会提供请求转发、安全认证(身份/权限认证)、流量控制、负载均衡、容灾、日志、监控这些功能。 上面介绍了这么多功能实际上网关主要做了一件事情:请求过滤 。权限校验、流量控制这些...

空空如也

空空如也

1 2
收藏数 32
精华内容 12
关键字:

tomcat监控连接请求地址