• 电商系统大访问量静态页优化架构


    javashop电商系统中像买家端首页、商品详情页、店铺首页等这类页面有两个共同的特点,即访问量大,数据不常变动。对于这类页面,为了减轻前端服务器的压力,javashop将这些页面缓存到了Redis中,当用户访问这些页面时,服务器会通过OpenResty代理执行lua脚本访问Redis中缓存的静态页面信息。接下来,我们来详细的讲解下整个流程中所涉及到的技术点。

    1、缓存静态页

    缓存静态页的过程在javashop中是通过httpClient抓取前端服务器中的静态页内容放到redis中。

      1)抓取静态页信息

    private String getHTML(String url, String type, int times) throws IOException {
        String html;
        // socket超时  connect超时
        RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(50000)
                .setConnectTimeout(50000)
                .build();
        CloseableHttpClient httpClient =HttpClients.custom().setDefaultRequestConfig(requestConfig).build();
        HttpGet httpGet = new HttpGet(url);
        httpGet.setHeader("Client-Type", type);
        CloseableHttpResponse response = httpClient.execute(httpGet);
        int status = response.getStatusLine().getStatusCode();
    
        if (status != 200) {
            html = EntityUtils.toString(response.getEntity(), "utf-8");
    
            debugger.log("生成静态页出错:静态页渲染服务返回" + status, "uri:" + url);
            debugger.log(html);
            if (times >= 4) {
                return ("create error ,return code is :" + status + ",url is :" + url);
            } else {
                times++;
                debugger.log(times + "次重试...");
                //重试时等待时间,在一段时间后重试   防止出现429(Too much connections in one mintue)问题 
                try {
                    Thread.sleep(times * 1000);
                } catch (InterruptedException e) {
                    logger.debug(e.getMessage());
                }
    
    
                html = getHTML(url, type, times);
    
                return html;
            }
    
        } else {
    
            if (times > 0) {
                debugger.log("重试成功");
            }
            html = EntityUtils.toString(response.getEntity(), "utf-8");
        }
    
        return html;
    }

      2)存入redis

    //生成消息
    String url = getUrl(path, type);
    //通过http 来获取html存储redis
    String html = this.getHTML(url, type);
    stringRedisTemplate.opsForValue().set(name, html);

    2、访问静态页

    OpenResty® 是一个基于 Nginx 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动态 Web 应用、Web 服务和动态网关。

    OpenResty官网地址:http://openresty.org/cn/

    下面我们着重介绍一下OpenResty是如何通过lua脚本访问redis的,以PC端静态页为例。

      1)首先我们准备好访问redis的lua脚本,代码如下

    单机版:single_connector.lua

    local request_uri = ngx.var.uri 
    local redis = require "resty.redis"
    local red = redis:new()
    
    --red:set_timeout(10000) -- 1 sec
    
    local ok, err = red:connect("ip", port)
    if not ok then
        ngx.say("failed to connect: ", err)
        return
    end
    
    --如果设置了密码请打开注释,并填写密码
    --local res, err = red:auth("password")
    --    if not res then
    --    ngx.say("failed to authenticate: ", err)
    --    return
    --end
    
    local res, err = red:get(request_uri)
    -- 请修改https://www.test.com 为实际配置域名或IP端口
    if res == ngx.null then
        ngx.redirect("https://www.test.com/404.html")
       return
    end
    
    if not res then
        ngx.say("failed to get: " .. request_uri , err)
        return
    end
    red:set_keepalive(6000,1000)
    ngx.say(res)

    集群版:cluster_connector.lua

    local request_uri = ngx.var.uri 
    local config = {
        name = "testCluster",                   --rediscluster name
        -- enableSlaveRead = true,
        serv_list = {                           --redis cluster node list(host and port),
            { ip = "ip", port = port },
            { ip = "ip", port = port }
        },
        keepalive_timeout = 60000,              --redis connection pool idle timeout
        keepalive_cons = 300,                  --redis connection pool size
        connection_timout = 15000,               --timeout while connecting
        max_redirection = 5                     --maximum retry attempts for redirection
    }
    
    local redis_cluster = require "resty.rediscluster"
    local red_c = redis_cluster:new(config)
    
    -- 请修改https://www.test.com 为实际配置域名或IP端口
    local v, err = red_c:get(request_uri)
    if v == ngx.null then
        ngx.redirect("https://www.test.com/404.html")
       return
    end
    
    if err then
        ngx.log(ngx.ERR, "err: ", err)
    else
        ngx.say(v)
    end

    注意:

    redis配置注释掉bind 127.0.0.1、设置protected-mode 为no;否则通过lua连接redis出错

      2)在OpenResty中配置server路径  

     #新建静态页输出节点,content_by_lua_file为lua脚本实际路径。
       server {
    
            listen       80;
            server_name  localhost; 
    
            #pc端静态响应
            location /PC {
               default_type text/html;
               content_by_lua_file "/usr/local/openresty/nginx/conf/lua/single_connector.lua"; 
    
               #redis集群请使用此配置 
               #content_by_lua_file "/usr/local/openresty/nginx/conf/lua/cluster_connector.lua";  
    
            }
    
        }
  • 相关阅读:
    dalvik浅析二:jni、so
    android apk壳
    prism4 StockTrader RI 项目分析一些体会
    PRISM ‘VS100COMNTOOLS’ not set. Cannot set the build environment
    安卓移动应用代码安全加固系统设计及实现
    手机游戏外挂技术研究与运用
    移动终端安全威胁与应对措施
    游戏软件反外挂技术方案的设计和安全解决方案
    网络安全等级保护 2.0 下的安全体系建设
    APP加密,ios代码混淆工具,虚拟化技术 适用于移动应用程序的虚拟化加密软件
  • 原文地址:https://www.cnblogs.com/javashop-docs/p/13737920.html
Copyright © 2020-2023  润新知