zoukankan      html  css  js  c++  java
  • 【Java】关于项目启动大请求量高负载时如何确保db等资源不出错的问题

    【Java】关于项目启动大请求量高负载时如何确保db等资源不出错的问题

     

    还记得当时来现在这家公司面试时, 有过一个问题:
    如果一个项目启动时(单机), 瞬间来了1000个访问, 如何确保db等资源不会压垮呢?

    现在想想我当时回答的并不好, 而现在看公司框架才发现其实有针对于这一块做过专门的优化的。
    下面就来分享下公司关于这个地方的处理, 一句话总结就是:项目启动时会先热身一段时间,概率性拒绝请求以保证服务的高可用。

    下面直接说原理:
    1, 根据自己的业务需求设置一个热身时间:warmupTime
    2, 在服务启动接收请求的时候添加一个拦截器,如果项目还没有热身完就概率性停止对外服务。(这里使用random去计算时候返回正常的响应)
    3, 等热身完毕的时候提供完整的响应。

    使用场景:
    特别适用于单机服务(双机因为有负载均衡所以不必考虑这个问题),且并发较高的服务。使用热身的主要原因是:当系统初始化时缓慢增加请求,防止系统开始压力过大导致db等资源出错。

    下面直接贴代码, 用代码来讲解:

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        processRequest(req, resp);
    }
    
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        processRequest(req, resp);
    }
    
    protected void processRequest(HttpServletRequest requestOld, HttpServletResponse response) throws ServletException, IOException {
        // 当系统初始化时缓慢增加请求,防止系统开始压力过大导致db等资源出错
    if (!bootHandler.isOk() && bootHandler.handle(requestOld, response,               config)) {
            return;
        }
        
        //...
    }

    在接收到请求时会先去判断是否热身完毕, bootHandler.handle就是判断热身的方法,具体判断方式如下代码:

    public boolean handle(HttpServletRequest request, HttpServletResponse response, MvcConfig config) throws IOException {
        long warmupTime = config.getWarmupTime();
        String startingUpJson = config.getStartingUpJson();
        if (warmupTime <= 0) {
            ok = true;
        } else {
            long now = System.currentTimeMillis();
            if (startTime == -1 || startTime == 0) {
                if (startTime == -1) {
                    startTime = now;
                    LOG.info("收到第一个请求,开始进行热身");
                }
                RenderUtils.renderJson(request, response, startingUpJson);
                return true;
            } else {
                //从开始时间到现在,以及配置的热身时间计算当前服务的比例
                if (now >= startTime + warmupTime) {
                    ok = true;
                } else {
                    //比率是从 [0-100)
                    int rate = (int) ((now - startTime) * 100 / warmupTime);
                    boolean rejected = random.nextInt(100) > rate;
                    if (rejected) {
                        if (now - lastLogTime.get() > 1000L) {
                            lastLogTime.set(now);
                            LOG.warn("当前请求被拒绝,当前响应概率为:{}%", rate);
                        }
                        renderJson(request, response, startingUpJson);
                        return true;
                    }
                }
            }
        }
        return false;
    }

    首先回去判断是否配置了热身时间, 如果没有配置那么直接返回。
    接着就去用当前的时间和项目启动时间以及热身时间计算出比率, 然后通过random去判断当前请求是否返回响应。直到热身完, 比率会达到100%。

    下面贴一张项目启动时的Log:

    虽然这是一种很简单的方式处理项目启动时资源不可用的解决方法, 但是却对项目启动时带来很大的帮助, 希望这种方法能够对大家有用

  • 相关阅读:
    Hibernate 3入門
    如何调整液晶显示器保护你的视力
    WEB前端开发经验总结实战篇
    【JS】引用类型之Array
    Oracle的DBA管理常用sql
    使用cos组建上传文件
    前台js将json转换成json对象的方法
    关于父页面访问iframe中元素和js的那点事
    数据库中IN和EXISTS的区别
    关于google浏览器有时莫名自动提交表单的问题
  • 原文地址:https://www.cnblogs.com/du-0210/p/8426377.html
Copyright © 2011-2022 走看看