精华内容
下载资源
问答
  • 从资源配置的角度分析
    千次阅读
    2022-02-20 13:06:18

    最近有段时间没搞项目部署了,结果在部署前端项目的时候,访问页面路由(不是根路径),nginx 响应都是 404,直接访问页面根路径,路由跳转到前端的 404 页面,排查了半天,这里再总结一下。

    1. 路由访问 404 问题

    前端单页应用路由分两种:哈希模式和历史模式。

    哈希模式部署不会遇到啥问题,但是一般只用于本地调试,没人直接部署到生产环境。历史模式的路由跳转通过 pushStatereplaceState 实现,不会触发浏览器刷新页面,不会给服务器发送请求,且会触发 popState 事件,进而监听路由变化渲染相应页面组件,因此可以实现纯前端路由。

    需要注意,使用历史模式的时候,还是有两种情况会导致浏览器发送请求给服务器:

    • 输入地址直接访问
    • 刷新页面

    在这两种情况下,如果当前地址不是根路径,因为都是前端路由,服务器端根本不存在对应的文件,则会直接导致 nginx 直接响应 404。因此需要在服务器端进行配置:

    server {
      listen 80;
      server_name www.example.com;
      location / {
        root /root/workspace/ruoyi-ui/dist;
    
        # history 模式重点就是这里
        try_files $uri $uri/ /index.html;
      }
    }
    

    try_files 的作用就是按顺序检查文件是否存在,返回第一个找到的文件。$uri 是 nginx 提供的变量,指当前请求的 URI,不包括任何参数

    当请求静态资源文件的时候,命中 $uri 规则;当请求页面路由的时候,命中 /index.html 规则

    至于直接访问页面根路径,会跳转到前端的 404 页面,这完全是前端路由配置问题。前端路由配置的时候,没有给根路径 / 配置规则,而对匹配不到路由的时候,配置了 404 页面,所以访问根路径会重定向到 404 页面,这个跳转是前端操作,与 nginx 无关。正常来说,前端路由配置的时候,都会给根路径 / 加一个匹配规则,例如根路径重定向到 index 路由,可以确保用户访问根路径可以正常展示页面。

    2. 非根路径部署访问 404 问题

    此外,在部署的时候不使用根路径,例如希望通过这样的路径去访问 /i/top.gif,如果直接修改 location 发现还会响应 404:

    location /i/ {
      root /data/w3;
      try_files $uri $uri/ /index.html;
    }
    

    这是因为 root 是直接拼接 root + location,访问 /i/top.gif,实际会查找 /data/w3/i/top.gif 文件

    这种情况下推荐使用 alias

    location /i/ {
      alias /data/w3;
      try_files $uri $uri/ /index.html;
    }
    

    alias 是用 alias 替换 location 中的路径,访问 /i/top.gif,实际会查找 /data/w3/top.gif 文件

    3. 接口请求代理

    现在页面部署成功了,但是接口请求会出错,这是因为还没有对接口请求进行代理,下面配置一下:

    location ^~ /prod-api/ {
    	proxy_set_header Host $http_host;
    	proxy_set_header X-Real-IP $remote_addr;
    	proxy_set_header REMOTE-HOST $remote_addr;
    	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    	proxy_pass http://192.168.31.101:8080/;
    }
    

    4. 两点补充

    除了匹配请求路径访问对应文件之外,还可以配置合理的缓存机制。由于 Webpack 打包会给静态资源加上哈希值,因此可以合理配置缓存规则,提升用户体验:

    • html 文件可以配置协商缓存
    • 静态资源文件由于带有哈希,可以配置一年强缓存,提升资源二次加载速度

    再注意下 location 的匹配优先级规则:

    • = 表示精确匹配。只有请求的url路径与后面的字符串完全相等时,才会命中。
    • ^~ 表示如果该符号后面的字符是最佳匹配,采用该规则,不再进行后续的查找。
    • ~ 表示该规则是使用正则定义的,区分大小写。
    • ~* 表示该规则是使用正则定义的,不区分大小写。

    nginx 的匹配优先顺序按照上面的顺序进行优先匹配,而且 只要某一个匹配命中直接退出,不再进行往下的匹配

    剩下的普通匹配会按照 最长匹配长度优先级来匹配,就是谁匹配的越多就用谁。

    nginx 每条规则都要以分号结尾,可以运行 nginx -tc nginx.conf 查看配置规则是否生效

    5. 完整的 nginx 配置

    server {
      listen 80;
      server_name www.example.com;
    
      # html 页面访问
      location /ruoyi/ {
        # 支持 /ruoyi 子路径访问
        alias /root/workspace/ruoyi-ui/dist;
    
        # history 模式重点就是这里
        try_files $uri $uri/ /index.html;
    
        # html 文件不可设置强缓存,设置协商缓存即可
        add_header Cache-Control 'no-cache, must-revalidate, proxy-revalidate, max-age=0';
      }
    
      # 接口请求代理
      location ^~ /prod-api/ {
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header REMOTE-HOST $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass http://192.168.31.101:8080/;
      }
    
      # 静态资源访问
      location ~* \.(?:css(\.map)?|js(\.map)?|gif|svg|jfif|ico|cur|heic|webp|tiff?|mp3|m4a|aac|ogg|midi?|wav|mp4|mov|webm|mpe?g|avi|ogv|flv|wmv)$ {
        # 静态资源设置一年强缓存
        add_header Cache-Control 'public, max-age=31536000';
      }
    }
    

    6. 总结

    单页应用历史模式路由,如果不是根路径,请求服务器都会响应 404,需要在服务器端配置 try_files 按顺序进行匹配,其中请求页面路由命中 /index.html 规则,请求静态资源命中 $uri 规则。

    当页面部署在子路径下的时候,使用 root 会拼接 root + location,使用 alias 则是用 alias 替换 location 中的路径。

    前端项目部署的时候,还需要配置接口请求代理。

    给 html 文件配置协商缓存,由于静态资源文件会带哈希,因此可以给静态资源文件配置强缓存。

    location 匹配的优先级规则注意下。

    参考

    前端到底用nginx来做啥

    一份简单够用的 Nginx Location 配置讲解

    更多相关内容
  • 产业转移会对承接地产业发展产生重要影响,通过建立模型并利用...转进产业的要素获取能力高于承接地已有产业,说明承接地已有产业的竞争力总体上弱于转进产业,并政府调控的角度提出促进二者共同发展耦合的政策建议。
  • 互联网是技术发展的一个必然产物,本文仅仅试图从资源配置角度来理解一下这些趋势背后的推动力,非业内人士,假语村言,博君一笑。 话说世界诞生之初,天地混沌如鸡子,盘古开天辟地,清上升为天、浊下沉...
    最近十几年来,以阿里巴巴、腾讯为代表的互联网公司快速崛起,呈现出以互联网为平台,各种产品和服务百花齐放百家争鸣,在方便人们的生产生活的同时,也改变了几代人的工作生活方式。比如,外出买东西无需现金信用卡,出现了所谓的“无现金城市”,出行可以手机叫滴滴或者骑共享单车,医院挂号、缴水电费都能够网上办理了,如果用网上流传的“吓尿指数”来看,这十几年应该可以算是一个吓尿周期了。
    互联网产业急速膨胀也带来软硬件技术的更新换代,比如云计算、大数据、人工智能、ICT融合等,在这些大概念的下面是各种不胜枚举的新的语言、框架、架构等,比如golang、异步IO、generator、容器、微服务、NoSQL、tensorflow等。
    互联网是技术发展的一个必然产物,本文仅仅试图从资源配置的角度来理解一下这些趋势背后的推动力,非业内人士,假语村言,博君一笑。

    话说世界诞生之初,天地混沌如鸡子,盘古开天辟地,清上升为天、浊下沉为地。我们已经无法回到过去,去体会盘古的一斧 神威开创了世界的进化,但是小时玩过泥浆的同学可能有体会,如果把一把泥沙放到装满水的瓶子里使劲晃晃,慢慢地,随着泥浆的旋转,大粒的沙石最先沉淀下来,然后是粗粒度的土块,最后在上面的非常纤细的泥土,时间足够的话,水又变得澄清了。从瓶子外面能够清楚地看到从下往上,粒度越来越细,越来越紧凑。作为一个彻底的无神论者,我时常感觉社会的进步、技术的发展都能够在简单的现象中找到某种隐喻,用程序员的语言讲,是某种映射(map)。
    互联网从来就没有凭空创造一个行业 ,它对传统产业进行了转换,以一种新的形态提供传统产业同样的服务或产品,比如,传媒+广告行业=>Google、百度,零售+商业地产收租=>电商阿里、京东,通信及周边=>微信、Facebook,出租车+租车=>Uber、滴滴。用一个数学公式表达的话就是g=f(x),x是传统产业,f是互联网,g就是互联网对传统产业改造的结果。

    如果以泥浆沉淀过程来对资源配置的发展做隐喻的话,我们能够从中悟到什么道理呢?那就是资源配置正从粗放变得集约,从笨重变得精细,从低效变得高效。如果将这个过程比作是在曲面上滚动的小球的话,那提升资源配置效率就是那个最快梯度,大势所趋、势不可挡。
    回过头来考虑一下互当今社会的几大场景:
    1.电商。没有人能否认电商对人们生活的巨大影响,淘宝、京东等B2C业务大大方便了人们的生活,释放了无数的购买欲望,产生了无数的“剁手党”。从资源配置的角度讲,电商首先将各种商品名录种类齐全地送到消费者手中,消费者足不出户就能够货比三家,了解商品的属性,挑选到符合自己需求的商品;其次,电商能够省去众多中间环节,商品交易链更短,交易更便捷,同时,现代物流业能够将商品快速直接从商家交到消费者手中;第三,大数据的运用,让电商能够揣摩消费者心理,精确推送商品广告,促进潜在需求的消费。以上种种,都提高了商品的流通精度和速度,更好地满足了消费者对各种“资源”的需求。
    2.共享经济。这个词应该是从滴滴开始的吧?顺风车,且不说政策上限制的问题,让广大车主在用车过程中,在有空闲座位、路线比较吻合的情况下,既方便了乘客,缓解了公共交通压力,利用了闲置资源,又给自己带来了一定的收益。进一步的,今年刚刚出现的共享单车、共享汽车,让出行工具在充分发挥代步功能的同时,省去了个人对工具的购买和维护。如果照这个趋势发展下去的话,公共交通和共享交通相互补充,用户只要为本次出行买单,不需要考虑车辆的维修保养、停车等,这样, 强化使用权、弱化所有权, 车辆的总量会下降,但是利用效率大大提高。
    3.农村土地的集中。这个不是IT领域的,但是代表了一类场景,就是资源的集中利用。 一滴水不是资源,但是一口井、一片湖面可以认为是资源,这体现了资源的聚集性。现代大机械化生产让农村土地改革以来形成的一家一户分散经营成了阻碍生产力提高的一个障碍,近年来,随着城市化和新农村政策等的推出,农村土地又呈现出由分散到集中的现象,让农场主拥有几百上千亩地成为可能,这就为机械化大生产提供了必要条件。这个场景比较特殊,因为从微观角度看,机械化对土地的利用不是更精细,而是更粗放,但是从宏观看,机械化生产提高了生产效率,节约了人力成本。原来一家一户用镰刀一上午能收割一亩的麦子,现在一台联合收割机一上午可能就可以收割几十上百亩地。

    再从软件工程师的角度看一下软件技术发展的几个场景:
    1.开源。且不管各种开源License背后的商业逻辑是什么,从实际效果看,开源软件可以称为现在软件行业的基石。经常有些“牛人”抱怨开源软件这个不好、那个不行,总想自己发明一个轮子,但是往往最终不是走了开源的老路,就是自己也看不下去,无力维护了。开源,体现了在软硬件行业对智力资源的共享利用,是将开发者的场景分析、架构设计、代码开发测试等资源全部共享出来,满足大家共同的需求。
    2.云计算。XaaS可能是在IT领域对资源配置优化说法最有力的一个证明了,比如Aws提供的IaaS,最初就是亚马逊将自己公司内部空闲的基础设施资源作为服务对外暴露出来,提供给外部用户,在使用过程中,所有用户共享计算、存储、网络等基础资源。是不是可以理解为,通过这样的资源优化配置,亚马逊将空闲的CPU时间、空闲的磁盘、空闲的带宽进行了变现?私有云,感觉有点类似于上面土地集中的场景,企业内部为了提高资源利用率,将各部门分散配置的服务器等软硬件设施集中起来,组建成私有云,对企业内部提供各种共享服务。
    3.面向对象。OOP这个概念现在可能挑不起程序员的任何胃口了,就像米饭一样,天天吃。但是在1995年对乔布斯的一次采访中,乔帮主在自豪地声称PC是人类历史上最伟大的发明,而他就在其中之后,预言OOP和互联网将是计算机行业发展的方向,可见OOP在当时的重要意义。如果说开源是在全世界程序员中共享资源的话,OOP就是在代码内部的微观层面进行的资源优化配置。高扇入、低扇出讲的是什么?就是我这里有资源,你们都用我这个就行,不要自己写了。

    假设资源的优化配置是各领域发展的驱动力,那如何发现下一个方向或者机会点呢?不妨做一个矩阵,横向是业务领域,纵向是发展方式:

    通过将已有的互联网公司填入上述表格,就不难发现哪里有空白了。
    当然上面的表格有些粗糙,肯定还有更多的维度可以去更好地理解这个过程,相信成功的创业者都是在对现状和趋势进行了多维度分析之后发现了相关空白领域,从而找到机会点。
    但是需要清醒地认识到,找到机会点只是万里长征第一步,如果不能有爬雪山、过草地的精神,没有四渡赤水的智慧和勇气,那找到机会点也毫无意义。


    展开全文
  • 县域金融资源配置效率分析,郑策,全颖,本文主要对县域金融资源配置效率进行分析金融与经济之间关系的角度,定性地分析了县域金融资源配置对县域经济和金融自身的影
  • 从资源体系、资源分布、资源日历、资源主导性、资源搭配、人力资源资源风险、资源优化等角度综合比较分析了Ms Project、P3、清华斯维尔、梦龙智能项目管理等项目管理软件中的资源管理理念、方式、功能,并就它们的...
  • 针对集团制造企业在制造资源配置过程中多主体、多任务、多资源、多工序以及协同性的特点,集团公司总体利益及下属企业个体利益多角度出发,综合考虑生产成本、加工资源、加工效率等多个因素,建立集团分布式制造资源...
  • 为了保证响应时间百分比SLA的同时,最小化商用云中心资源配置成本,基于排队理论提出了云中心模型,经济角度分析云中心资源配置成本,并推导出云中心响应时间百分比的数学表达式。给出了计算最小配置成本算法...
  • 资源是一篇由本人编写的金融工程方向的数学建模论文,主要涉及相关性计算,统计制图,历史数据法,数据处理。算法以及模型大部分为经典模型的引用
  • 统一 Angular 5和基于Java的人力资源分析工具 ... 如果要Idea运行后端,则应在运行配置中选择./server文件夹中的工作目录。 运行客户端 cd client npm run dev-local 调试应用程序 mvn clean install j
  • 企业资源配置力与企业竞争力.doc
  • 做一个积极的人 编码、改bug、提升自己 我有一个乐园,面向编程,春暖花开! 你好,JedisPoolConfig Java中使用Jedis作为...本文简单总结几个常用的配置,然后通过源码(版本jedis-3.1.0)的角度让你理解配置这些...

    做一个积极的人

    编码、改bug、提升自己

    我有一个乐园,面向编程,春暖花开!

    你好,JedisPoolConfig

    Java中使用Jedis作为连接Redis的工具。在使用Jedis的也可以配置JedisPool连接池,JedisPool配置参数大部分是由JedisPoolConfig的对应项来赋值的。本文简单总结几个常用的配置,然后通过源码(版本jedis-3.1.0)的角度让你理解配置这些参数的原理。

    首先了解一下池化((对象池、数据库连接池、线程池等等))的一些思想和好处。方便后面对JedisPoolConfig的配置的理解。

    池化的基本思想

    1、可以在初始化的时候创建一些对象,当有需要使用的时候不直接从池中获取,提高响应速度;

    2、使用过的对象不进行销毁,保存起来,等下一次需要对象的时候,拿出来重复使用,减少频繁创建对象所造成的开销;

    3、创建的对象统一保存,方面管理和维护。

    池化好处总结

    1、提高响应的速度

    2、降低资源的消耗

    3、方便管理和维护

    JedisPoolConfig配置说明

    类图和源码解析

    首先看一下类图:

    UTOOLS1571543704493.png

    • BaseGenericObjectPool:封装公共的配置的参数。
    private long maxWaitMillis = DEFAULT_MAX_WAIT_MILLIS;
    	// DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS = 1000L * 60L * 30L
        private long minEvictableIdleTimeMillis =
                DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS;
    
    	// DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS = -1L
     	private long timeBetweenEvictionRunsMillis =
                DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS;
    
    	// DEFAULT_NUM_TESTS_PER_EVICTION_RUN = 3
        private int numTestsPerEvictionRun =
                DEFAULT_NUM_TESTS_PER_EVICTION_RUN;
    
    	// DEFAULT_TEST_ON_CREATE = false
        private boolean testOnCreate = DEFAULT_TEST_ON_CREATE;
    	// DEFAULT_TEST_ON_BORROW = false
        private boolean testOnBorrow = DEFAULT_TEST_ON_BORROW;
    	// DEFAULT_TEST_ON_RETURN = false
        private boolean testOnReturn = DEFAULT_TEST_ON_RETURN;
    	// DEFAULT_TEST_WHILE_IDLE = false
        private boolean testWhileIdle = DEFAULT_TEST_WHILE_IDLE;
    	//...
    }
    
    • GenericObjectPoolConfig:继承BaseGenericObjectPool,内部代码很简单,封装了GenericObjectPool的配置。主要是maxTotalmaxIdleminIdle
      此类不是线程安全的;它仅用于提供创建池时使用的属性。在创建单例的JedisPool 使用JedisPoolConfig需要注意线程安全问题,下面会有个demo介绍创建单例JedisPool
    public class GenericObjectPoolConfig<T> extends BaseObjectPoolConfig<T> {
    
        /**
         * The default value for the {@code maxTotal} configuration attribute.
         * @see GenericObjectPool#getMaxTotal()
         */
        public static final int DEFAULT_MAX_TOTAL = 8;
        // ...
    
    	// DEFAULT_MAX_TOTAL = 8
        private int maxTotal = DEFAULT_MAX_TOTAL;
    	// DEFAULT_MAX_IDLE = 8
        private int maxIdle = DEFAULT_MAX_IDLE;
    	// DEFAULT_MIN_IDLE = 0
        private int minIdle = DEFAULT_MIN_IDLE;
        // ...
    }
    
    • JedisPoolConfig继承了上面的优良基因,然后又对其他的几个设置属性重新设值。

    为了方便使用,Jedis提供了JedisPoolConfig,它继承了GenericObjectPoolConfig在空闲检测上的一些设置。

    public class JedisPoolConfig extends GenericObjectPoolConfig {
      public JedisPoolConfig() {
        // defaults to make your life with connection pool easier :)
        setTestWhileIdle(true);
        setMinEvictableIdleTimeMillis(60000);
        setTimeBetweenEvictionRunsMillis(30000);
        setNumTestsPerEvictionRun(-1);
      }
    }
    

    配置参数解析

    JedisPoolConfig中可以能够配置的参数有很多,连接池实现依赖apache 的commons-pool2。上面源码也大致列举了一些配置参数,下面在详细说明一下。

    把池理解为工厂,池中的实例理解为工人,如下图,这样池中的很多参数理解起来就比较容易了。

    UTOOLS1571546063571.png

    Jedis连接就是连接池中JedisPool管理的资源,JedisPool保证资源在一个可控范围内,并且保障线程安全。使用合理的GenericObjectPoolConfig配置能够提升Redis的服务性能,降低资源开销。下列两表将对一些重要参数进行说明,并提供设置建议。

    参数说明默认值建议
    maxTotal资源池中的最大连接数8参见关键参数设置建议
    maxIdle资源池允许的最大空闲连接数8参见关键参数设置建议
    minIdle资源池确保的最少空闲连接数0参见关键参数设置建议
    blockWhenExhausted当资源池用尽后,调用者是否要等待。只有当值为true时,下面的maxWaitMillis才会生效。true建议使用默认值。
    maxWaitMillis当资源池连接用尽后,调用者的最大等待时间(单位为毫秒)。-1(表示永不超时)不建议使用默认值。
    testOnBorrow向资源池借用连接时是否做连接有效性检测(ping)。检测到的无效连接将会被移除。false业务量很大时候建议设置为false,减少一次ping的开销。
    testOnReturn向资源池归还连接时是否做连接有效性检测(ping)。检测到无效连接将会被移除。false业务量很大时候建议设置为false,减少一次ping的开销。
    jmxEnabled是否开启JMX监控true建议开启,请注意应用本身也需要开启。

    空闲Jedis对象检测由下列四个参数组合完成,testWhileIdle是该功能的开关。

    名称说明默认值建议
    testWhileIdle是否开启空闲资源检测。falsetrue
    timeBetweenEvictionRunsMillis空闲资源的检测周期(单位为毫秒)-1(不检测)建议设置,周期自行选择,也可以默认也可以使用下方JedisPoolConfig 中的配置。
    minEvictableIdleTimeMillis资源池中资源的最小空闲时间(单位为毫秒),达到此值后空闲资源将被移除。180000(即30分钟)可根据自身业务决定,一般默认值即可,也可以考虑使用下方JeidsPoolConfig中的配置。
    numTestsPerEvictionRun做空闲资源检测时,每次检测资源的个数。3可根据自身应用连接数进行微调,如果设置为 -1,就是对所有连接做空闲监测。

    说明 可以在org.apache.commons.pool2.impl.BaseObjectPoolConfig中查看全部默认值。

    关键参数设置建议

    maxTotal(最大连接数)

    想合理设置maxTotal(最大连接数)需要考虑的因素较多,如:

    • 业务希望的Redis并发量;
    • 客户端执行命令时间;
    • Redis资源,例如nodes (如应用个数等) * maxTotal不能超过Redis的最大连接数;
    • 资源开销,例如虽然希望控制空闲连接,但又不希望因为连接池中频繁地释放和创建连接造成不必要的开销。

    假设一次命令时间,即borrow|return resource加上Jedis执行命令 ( 含网络耗时)的平均耗时约为1ms,一个连接的QPS大约是1000,业务期望的QPS是50000,那么理论上需要的资源池大小是50000 / 1000 = 50。

    但事实上这只是个理论值,除此之外还要预留一些资源,所以maxTotal可以比理论值大一些。这个值不是越大越好,一方面连接太多会占用客户端和服务端资源,另一方面对于Redis这种高QPS的服务器,如果出现大命令的阻塞,即使设置再大的资源池也无济于事。

    maxIdle与minIdle

    maxIdle实际上才是业务需要的最大连接数,maxTotal 是为了给出余量,所以 maxIdle 不要设置得过小,否则会有new Jedis(新连接)开销,而minIdle是为了控制空闲资源检测。

    连接池的最佳性能是maxTotal=maxIdle,这样就避免了连接池伸缩带来的性能干扰。但如果并发量不大或者maxTotal设置过高,则会导致不必要的连接资源浪费。

    您可以根据实际总QPS和调用Redis的客户端规模整体评估每个节点所使用的连接池大小。

    使用监控获取合理值

    在实际环境中,比较可靠的方法是通过监控来尝试获取参数的最佳值。可以考虑通过JMX等方式实现监控,从而找到合理值。

    上面参数配置:JedisPool资源池优化

    创建JedisPool代码

    // volatile 修饰
    private static volatile JedisPool jedisPool = null;
    
    private JedisPoolUtils(){
    }
    
    public static JedisPool getJedisPoolInstance() {
        // 使用双重检查创建单例
        if(null == jedisPool) {
            synchronized (JedisPoolUtils.class) {
                if(null == jedisPool) {
                    JedisPoolConfig poolConfig = new JedisPoolConfig();
                    poolConfig.setMaxTotal(10);
                    poolConfig.setMaxIdle(10);
                    poolConfig.setMinIdle(2);
                    poolConfig.setMaxWaitMillis(30*1000);
                    poolConfig.setTestOnBorrow(true);
                    poolConfig.setTestOnReturn(true);
                    poolConfig.setTimeBetweenEvictionRunsMillis(10*1000);
                    poolConfig.setMinEvictableIdleTimeMillis(30*1000);
                    poolConfig.setNumTestsPerEvictionRun(-1);
                    jedisPool = new JedisPool(poolConfig,"localhost",6379);
                }
            }
        }
        return jedisPool;
    }
    

    实例创建和释放大致流程解析

    UTOOLS1571556369669.png

    根据流程进行源码解析

    创建过程

    使用pool.getResource()进行Jedis实例的创建。

    //org.apache.commons.pool2.impl.GenericObjectPool#borrowObject(long)
    public T borrowObject(final long borrowMaxWaitMillis) throws Exception {
    
        final boolean blockWhenExhausted = getBlockWhenExhausted();
    
        PooledObject<T> p = null;
        boolean create;
        final long waitTime = System.currentTimeMillis();
    
        while (p == null) {
            create = false;
            // 从空闲队列中获取
            p = idleObjects.pollFirst();
            if (p == null) {
                // 创建实例
                p = create();
                if (p != null) {
                    create = true;
                }
            }
            // 吃资源是否耗尽
            if (blockWhenExhausted) {
                if (p == null) {
                    // 等待时间小于0
                    if (borrowMaxWaitMillis < 0) {
                        p = idleObjects.takeFirst();
                    } else {
                        p = idleObjects.pollFirst(borrowMaxWaitMillis,
                                                  TimeUnit.MILLISECONDS);
                    }
                }
                if (p == null) {
                    throw new NoSuchElementException(
                        "Timeout waiting for idle object");
                }
            } else {
                if (p == null) {
                    throw new NoSuchElementException("Pool exhausted");
                }
            }
            if (!p.allocate()) {
                p = null;
            }
    
            if (p != null) {
                try {
                    // 重新初始化要由池返回的实例。
                    factory.activateObject(p);
                } catch (final Exception e) {
    
                }
            }
        }
        updateStatsBorrow(p, System.currentTimeMillis() - waitTime);
    
        return p.getObject();
    }    
    
    

    释放过程

    从Jedis3.0版本后pool.returnResource()遭弃用,官方重写了Jedis的close方法用以代替;官方建议应用redis.clients.jedis#Jedis的close方法进行资源回收,官方代码如下:

     @Override
      public void close() {
        if (dataSource != null) {
          JedisPoolAbstract pool = this.dataSource;
          this.dataSource = null;
          if (client.isBroken()) {
            pool.returnBrokenResource(this);
          } else {
            pool.returnResource(this);
          }
        } else {
          super.close();
        }
      }
    

    这里主要看:pool.returnResource(this);

    //org.apache.commons.pool2.impl.GenericObjectPool#returnObject
    public void returnObject(final T obj) {
        // 获取要释放的实例对象
        final PooledObject<T> p = allObjects.get(new IdentityWrapper<>(obj));
    
        if (p == null) {
            if (!isAbandonedConfig()) {
                throw new IllegalStateException(
                    "Returned object not currently part of this pool");
            }
            return; // Object was abandoned and removed
        }
    	// 将对象标记为返回池的状态。
        markReturningState(p);
    
        final long activeTime = p.getActiveTimeMillis();
    	
        // 这里就和上面配置的参数有关系,释放的时候是否做连接有效性检测(ping)
        if (getTestOnReturn() && !factory.validateObject(p)) {
            try {
                destroy(p);
            } catch (final Exception e) {
                swallowException(e);
            }
            try {
                ensureIdle(1, false);
            } catch (final Exception e) {
                swallowException(e);
            }
            updateStatsReturn(activeTime);
            return;
        }
    	
    	// 检查空闲对象,如果最大空闲对象数小于当前idleObjects大小,则销毁
        final int maxIdleSave = getMaxIdle();
        if (isClosed() || maxIdleSave > -1 && maxIdleSave <= idleObjects.size()) {
            try {
                destroy(p);
            } catch (final Exception e) {
                swallowException(e);
            }
        } else {
            // 否则加入到空闲队列中,空闲队列是一个双端队列
            // getLifo 也和配置的参数有关,默认True
            if (getLifo()) {
                // last in first out,加到队头
                idleObjects.addFirst(p);
            } else {
                // first in first out ,加到队尾
                idleObjects.addLast(p);
            }
        }
        updateStatsReturn(activeTime);
    }
    

    上面创建和释放删除了一些代码,具体完整代码都是在GenericObjectPool类中。

    小结,后悔有期

    看完本文,应该大致对JedisPoolConfig有了一定的了解,指定里面的一些配置参数,并且能够基本的参数调优,以及实例资源的创建和释放的过程。

    如果感谢兴趣的伙伴可以下载Jedis的源码进行阅读和学习,掌握了JedisPoolConfig的配置,其他池化框架的配置也是大同小异,举一反三! 江湖不远,后会有期!

    如果需要Reids相关的资源可以扫码下方二维码,里面有Redis的相关资源!

    备注: 由于本人能力有限,文中若有错误之处,欢迎指正。


    谢谢你的阅读,如果您觉得这篇博文对你有帮助,请点赞或者喜欢,让更多的人看到!祝你每天开心愉快!


    Java编程技术乐园:一个分享编程知识的公众号。跟着老司机一起学习干货技术知识,每天进步一点点,让小的积累,带来大的改变!

    扫描关注,后台回复【秘籍】,获取珍藏干货! 99.9%的伙伴都很喜欢

    image.png | center| 747x519

    ©每天都在变得更好的阿飞云
    展开全文
  • 资源合理配置是水资源规划的核心部分,也是实现水资源可持续利用的有效措施之一,要解决辽宁...本文围绕辽宁省的具体情况对水资源状况和存在问题进行分析,并资源规划角度提出辽宁省水资源合理配置的对策及建议。
  • 市场环境下高校教师人力资源配置的几点思考,蔡简建,胡赤弟,师资市场角度分析高校师资配置,总结计划经济和市场经济下高校教师人力资源配置模式,结合制度经济学理论,提出了在当前的市
  • 数学建模高教社杯2015B “互联网+”时代的出租车资源配置论文解读 真题 首先展示一下2015B的原题是什么,如下 1B27002-B013解读 我们先大概的看看这篇论文的结构 模型假设 因为在现实中,许多情况没有我们想象的那么...

    数学建模高教社杯2015B “互联网+”时代的出租车资源配置论文解读

    真题

    首先展示一下2015B的原题是什么,如下
    在这里插入图片描述

    1B27002-B013解读

    我们先大概的看看这篇论文的结构
    在这里插入图片描述

    模型假设

    因为在现实中,许多情况没有我们想象的那么好,比如有些司机不使用打车软件,某些区域,比如学校,商场打车的比率更高,在没有打车软件的情况下,有些司机会挑选自己喜欢的路段接受乘客,而如果要把所有的因素全部考虑进去的话显然是一个非常大的工作量而且不太现实,所以作者给出了限定条件,也是每一篇建模论文都必须存在的部分 模型假设
    在这里插入图片描述

    问题解读

    其他几个部分都是格式规范,就不仔细介绍了,可以自己去看看文章,接下来就进入正文部分
    首先,这个题目是需要我们自己来收集数据的,所以对于各个问题,我们要抓住重点,第一步是明确应该如何收集数据
    下面.我们就一步一步的来看这个问题

    1.第一问

    • 试建立合理的指标,并分析不同时空出租车资源的“供求匹配”程度。

    数据采集

    很明显,问题提到了不同时空,这说明了我们要收集是数据需要有一定的时间空间跨度
    收集的数据对象则很明显是出租车
    对于数据采集部分我觉得大多数人只要看的用心点就能分析出要收集什么样的数据,关键是对于不同时空这个限制条件,我们如何能找出具有代表性,方便我们建立模型的数据

    本篇论文对于不同时空做出划分如下

    • 时间
      • 高峰时段
      • 常规时段
    • 空间
      • 市区
      • 郊区

    下面是该论文对问题一的分析,显然对于本题,作者选取了里程利用率和供求比率作为指标
    在这里插入图片描述
    下面我们看看这为什么要选取这两个指标作为问题一的答案

    指标确立

    作者对于里程利用率给出了分析,语言简洁,思路清晰,我们可以看到里程利用率其实就是出租车载客的效率
    载客效率高可以说明 供求关系紧张 因为司机载的乘客多,所以乘客相应的会难打到车
    载客效率低可以说明 供求关系宽松 因为司机载的乘客少,所以乘客相应的会容易打到车
    在这里插入图片描述
    下面是作者对供求比率的分析
    这也很好理解,总得来说就是供求程度一共有三种情况,抽象到数学公式就是η与1的大小比较在这里插入图片描述

    模型建立

    很明显,这题就是对两个指标的分析
    作者的思路是先确定两个指标的理想值

    里程利用率理想值的确定

    本文中作者从两个角度测量载客总里程

    • 供给角度
    • 需求角度

    在这里插入图片描述
    这个公式就是 载 客 里 程 总 里 程 \frac{载客里程}{总里程} 我觉得作者介绍的已经很清晰了


    移项一下就得到了下面的等式
    在这里插入图片描述下面是从需求角度,也就是坐车的顾客角度出发的,虽然不知道为什么要这么假设,但是可以看懂,发现作者考虑的角度还是蛮周全的
    在这里插入图片描述
    如果上述两个角度的里程数相等,我们就可以推出理想值的里程利用率是什么
    也就是作者在文中计算出的在这里插入图片描述

    供求比率理想值的确定

    在这里插入图片描述
    下图就是一个四边形区域,里面的黑点就是人,❉代表的是出租车在这里插入图片描述
    根据之前的公式 供 求 比 = 市 场 客 供 总 额 需 求 总 额 供求比=\frac{市场客供总额}{需求总额} =
    该文章得出了如下的等式
    很好理解,S就是出租车量,D就是顾客需求量,因为本文划分了n个四边形区域,所以累加求个和就好了
    在这里插入图片描述
    之前说过了供求关系分为三种情况,相应的作者做出了如下的公式
    文章中的推导十分有条理,也很详细, 看看就知道了
    在这里插入图片描述
    下面的公式才是正确的公式,不过该文章没有给出推导过程,只是写了通过查阅相关资料,其实就是把 η Ⅲ η_{Ⅲ} η取了个倒数,不然会出问题,因为 η Ⅲ η_{Ⅲ} η本身是小于1的
    在这里插入图片描述
    接下来作者做的事情是把两个理想值作为平衡点,其他的值作相应的归一化处理
    最后通过归一化后的结果,一个个二维的点,取他们到原点的举例作为不平衡度
    这个也很好理解,归一化之后,离原点的距离越大,就说明了之前的数据距离平衡点越远,显然这样的点匹配度越差
    在这里插入图片描述

    模型求解

    模型已经建立好了,下面的步骤就相对来说简单多了,本文作者选用了西安为案例
    在这里插入图片描述
    直接带入搜集到的数据,就可以得到了理想值
    下面就是画图,分别从之前说过的时间空间角度绘制出供求比率的变化程度,然后加一点分析就好了

    • 时间
      • 高峰时段
      • 常规时段在这里插入图片描述
    • 空间
      • 市区
      • 郊区
        分析什么的就是把图像大概说一说,总结一下第一问的结论,用普通人看的懂的语言表达出来在这里插入图片描述

    2.第二问

    • 分析各公司的出租车补贴方案是否对“缓解打车难”有帮助?

    在我看来这个问题就是考察的补贴方案对各个因素的影响,最后得出一个结论,有无帮助,根据现实来说,肯定是有的

    先看看作者对问题二的分析
    作者的思路很清晰,将补贴从下面两个角度考虑,最后对比有无补贴的情况就好了

    • 补贴
      • 乘客
      • 司机

    在这里插入图片描述
    针对两个人群,作者先绘制出了推图像,求出了两种平均补贴金额
    在这里插入图片描述
    然后作者确立了软件的使用人数比例与补贴金额的关系.画了两张图
    在这里插入图片描述
    根据作者的问题分析,还需要确立意愿半径,意思就是司机在多大距离内原有来接单
    作者查阅了耗油量,油价,结合补贴得出了表达式
    在这里插入图片描述
    上面这些都是很基本的操作,下面是模型的流程图

    模型建立

    看上去很复杂,其实就是从有没有使用打车软件来考虑,求出两种情况下的人均车辆占有率
    在这里插入图片描述
    作者在这里考虑的十分详细,接下里的文章里就对各个情况作出了说明,最后计算出w(缓解率),它的含义是该式用来表示使用补贴方案后与使用前相比的打车难的缓解程度
    在这里插入图片描述
    最后作者把各个时间段的缓解率绘制了个图像
    在这里插入图片描述
    又得出了一点分析,总的来说这道题的难度不大,主要考察的是思考问题的仔细程度
    在这里插入图片描述
    ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200715124936459.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1dlYXJ5X1BK,size_16,color_FFFFFF,t_70

    3.问题3

    • 如果要创建一个新的打车软件服务平台,你们将设计什么样的补贴方案,并论证其合理性。

    这道题跟第二问有着一定的联系,我们之前验证了政府给出的补贴方案是有利的,只不过这个问题我们需要求解出一个最优的补贴值,需要换一个角度思考问题,当然不能简单的套套第二问的公式
    下面看看作者给出的问题三的分析在这里插入图片描述

    模型建立

    这道题的思考空间大了许多,作者对于补贴的政策作出了更加详细的说明,并且从实际的角度论述了他们的可行性
    在这里插入图片描述
    作者从总体到局部进行分析,通过建立方程组来求解平均补贴

    **加粗样式**
    在这里插入图片描述
    九个区域的平均补贴已经求解出来了,也就是空间的划分已经完成
    除此之外,还需要考虑时间的划分,作者另外提取出了高峰时段,把高峰时段的补贴提高为2倍,得出了如下的等式
    在这里插入图片描述

    模型求解

    针对确定好的模型,作者首先绘制出了自己手收集到的数据表,乘客司机分布图,最后求解出了动态补贴方案
    在这里插入图片描述
    后面两大块也是论文里面必须有的,看看作者是怎么说的吧

    模型评价

    在这里插入图片描述

    模型的改进与推广

    在这里插入图片描述

    读后感

    在这里插入图片描述
    总的来说,这篇文章可以学习的点还是很多的,我们需要有一个严密的思维,并且在分析问题的时候考虑到各方面的因素,才可以在数学建模比赛中获得一个良好的成绩
    切忌:虽然每一问之间都有着联系,但是对于每一问的侧重点不同,我们不能把之前的模型直接拿来用,不然就凉凉
    对于这种社会型的问题来说,一般最后一问都会问的比较开放,这便需要我们的思维能力

    展开全文
  • 接下来我们由下往上详细分析。 物理层:顾名思义,就是用来存储数据的各种设备。企业级存储中的存储介质包括机械磁盘(HDD)、固态硬盘(SSD)、磁带(TAPE)、光盘(Optical Disk)等,其中最常见的是以HDD和SSD为...
  • 测试流程角度,对产品质量的一些总结思考一、熟悉的场景二、测试流程拆解分析1、需求评审2、技术设计评审3、测试方案设计4、线下测试(含灰度)5、线上测试6、测试复盘7、线上监控三、总结 一、熟悉的场景 生产...
  • 对国内外高等教育资源配置转型程度的研究现状、本课题的理论研究假设、基本推论、分析模式和指标体系进行综述和概括,构建我国高等教育资源配置转型程度研究的分析框架,以期推动该领域的研究不断深入。 关键词:高等...
  • 工程应用角度详述了计算满足电力系统运行规范、微电网友好接入条件的联络线功率限值的方法,作为风光储容量配置模型的约束条件;针对容量配置模型的求解,提出了基于限定搜索范围、增加随机个体等措施的改进遗传...
  • Mybatis配置文件——全配置解析

    万次阅读 2022-07-20 14:24:02
    为了让大家方便的使用,特意把总结放在文章开头,有帮助到你就点个关注呗配置名称配置含义配置简介包裹所有配置标签整个配置文件的顶级标签properties属性该标签可以引入外部配置的属性,也可以自己配置。该配置标签...
  • 多维分析在报表分析的基础上业务场景多个维度进行深入的探索式的分析一个多维分析表是由维指标多种配置分析范围这几个方面组成其中指标表示要分析的对象维是指分析问题的角度表示对指标要哪些方面来分析而...
  • 交易费用的角度对企业应用虚拟人力资源的机理进行了研究 .首先对虚拟人力资源的成本进行了分析 ,其次 ,研究了虚拟人力资源的规模问题 ,最后探讨了公司治理环境对配置...
  • 运用面向对象技术剖析资源模型的内涵,基于系统用户的需求构建二维模型结构框架:有形能力资源对象类和无形能力资源对象类,它们不同的角度、不同的层次描述企业的制造能力。在此框架基础上建立基于中性机制的STEP...
  • 为了缓解受新冠肺炎影响的港口作业效率低下的问题,请用数学建模的方 法解决以下五个问题: 问题1:请结合附件1的数据和您的合理假设,船公司联合对接的角度出发, 提供船公司之间的合作模式,以缓解港口拥堵或...
  • 为了全面理解城市化过程中耕地资源的配置效率及其动态过程,文章在揭示了城市化过程中...结果表明其耕地转用效率出现波动性变化,并随考察的角度不同而变化,在此基础上提出了提高城市化过程中耕地资源配置效率的建议。
  • 水的供给和需求角度分析了水资源紧缺原因,其中供给角度造成的紧缺有资源型紧缺、水质型紧缺和工程型紧缺,需求角度造成的紧缺有结构型紧缺、效率型紧缺和价格型紧缺 。针对紧缺原因,提出了被动型、主动型和混合型3...
  • 大型科学仪器设备是重要的科技基础条件资源,价值区间、购置时期、产地、经费来源、仪器类型、区域集中度、运行情况和共享情况等多个角度分析比较了江浙两省大型科学仪器设备的现状差异,并经济及资源总量、区域...
  • 0开始搭建R语言数据分析平台 本文实用的角度一步步搭建一个基于R语言的数据分析和可视化作图平台完成相关的系统配置和软件设置达到拿来即用的目的本文是R语言基础系列的第一篇该系列共分3篇第二篇讲R语言的基本...
  • 本文在梳理和分析了以往研究成果的基础上,区域经济资源配置角度分析了互联网与区域经济的关系。 通过互联网的发展分析时空演变,区域经济和区域经济的资源分配以及经济学的关联理论,微观和宏观的角度分析和...
  • 0 开始搭建 R 语言数据分析平台 本文实用的角度一步步搭建一个基于 R 语言的数据分析和可 视化作图平台完成相关的系统配置和软件设置达到拿来即 用的目的本文是 R 语言基础系列的第一篇该系列共分 3 篇 第二篇...
  • Yarn资源请求处理和资源分配原理解析

    万次阅读 多人点赞 2017-12-14 09:57:31
    FairScheduler的资源调度原理和代码 FairScheduler的调度概览 两种调度时机-心跳调度和持续调度 开始进行资源调度 判断这个application是否适合在这个节点上分配资源运行 YARN请求资源时的locality和relaxility限定 ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 141,806
精华内容 56,722
关键字:

从资源配置的角度分析