Java中池化技术探讨

news2024/11/19 21:32:24

背景:在日常开发中,除了考虑IO操作、线程上下文切换、GC的影响性能外。还通过池化技术提高性能通过循环复用资源,降低资源创建和销毁带来的开销和损失,从而提高性能,例如对象池、内存池、线程池、连接池

一、对象池(JedisPool举例) 

        1、jedis对象池和非对象池测试用例对比,使用池化技术很大提高OPS性能,测试如下     

package com.sk.pool.memory;

import com.sk.util.DateTimeUtils;
import org.openjdk.jmh.annotations.*;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

import java.util.UUID;
import java.util.concurrent.TimeUnit;

@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.SECONDS)
@Warmup(iterations = 5, time = 1)//预热 5 轮,每次 1s
@Measurement(iterations = 5, time = 1)//测试 5 轮,每次 1s
@Fork(2)//2个线程
@State(Scope.Benchmark)
public class RedisTest {
    JedisPool pool = new JedisPool("172.17.1.150", 6379);

    @Benchmark
    public void redisPool() {
        Jedis jedis = pool.getResource();
        jedis.auth("***");
        jedis.set("value", DateTimeUtils.getCurrentDateTime());
        jedis.close();
    }

    @Benchmark
    public void redisSimple() {
        Jedis jedis = new Jedis("172.17.1.150", 6379);
        jedis.auth("***");
        jedis.set("value", DateTimeUtils.getCurrentDateTime());
        jedis.close();
    }
}

        pom.xml引用文件

    <dependencies>
        <!-- jhm工具包 -->
        <dependency>
            <groupId>org.openjdk.jmh</groupId>
            <artifactId>jmh-core</artifactId>
            <version>1.21</version>
        </dependency>
        <dependency>
            <groupId>org.openjdk.jmh</groupId>
            <artifactId>jmh-generator-annprocess</artifactId>
            <version>1.21</version>
            <scope>provided</scope>
        </dependency>

        <!--redis工具包-->
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>2.7.1</version><!--版本号-->
        </dependency>
    </dependencies>

        JMH结果为

         2、reids对象池管理分析

        Jedis jedis = pool.getResource();

--main入口
Jedis jedis = pool.getResource();


--pool class
public T getResource() {
    try {
      return internalPool.borrowObject();
    } catch (Exception e) {
      throw new JedisConnectionException("Could not get a resource from the pool", e);
    }
  }

--GenericObjectPool class
public T borrowObject(final Duration borrowMaxWaitDuration) throws Exception {
        ...省略

        PooledObject<T> p = null;
        boolean create;
        while (p == null) {
            create = false;
            //对象池获取对象
            p = idleObjects.pollFirst();
            if (p == null) {
                //对象池未获取到,创建对象
                p = create();
                if (p != null) {
                    create = true;
                }
            }
            
        ...省略

        return p.getObject();
    }


private PooledObject<T> create() throws Exception {
        ...省略
        final PooledObject<T> p;
        try {
            p = factory.makeObject();
        ...省略
        return p;
    }

--jedisFactory class
public PooledObject<Jedis> makeObject() throws Exception {
    final HostAndPort hostAndPort = this.hostAndPort.get();
    final Jedis jedis = new Jedis(hostAndPort.getHost(), hostAndPort.getPort(), this.timeout);
    --redis连接
    jedis.connect();
    if (null != this.password) {
      jedis.auth(this.password);
    }
    if (database != 0) {
      jedis.select(database);
    }
    if (clientName != null) {
      jedis.clientSetname(clientName);
    }
    --返回reids连接对象
    return new DefaultPooledObject<Jedis>(jedis);
  }

        对象池管理工具类GenericObjectPool依赖Java公用的池化包commons-pool2实现对象池化管理

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-pool2</artifactId>
    <version>2.11.1</version>
</dependency>

        3、对象池管理生命周期,参数设置建GenericObjectPoolConfig

        

转载:面试官:Java 池化技术你了解多少?_肥肥技术宅的博客-CSDN博客

二、内存池(netty4举例 时间有限后续补充)

        内存池技术原理:【池化技术】内存池技术原理和C语言实现_小熊coder的博客-CSDN博客

  

三、线程池

        线程池技术原理想必都知道,这里不赘述       

   集成多线程怎么保证以下两点:

        1、性能稳:怎样保证不知道业务量总数情况下采用多线程 线程队列池:

                java.util.Queue 线程隔离器:

                CyclicBarrier 或 CountDownLatch

                锁

                任务执行器(对外)

        2、逻辑稳:怎样使改造后逻辑出错率接近为0

                逻辑侵入 接近 0

/*
 * 线程处理接口
 * */
public interface ThreadFacade<T, R> {
    /*
     * 返回任务集合
     * */
    public List<R> execute(List<T> task);
}

/*
* 任务执行器
* */
public interface TaskThreadFacade<T,R> {
    //任务执行
    R execute(T t);
}
public class ThreadTemplate<T,R> implements TaskThreadFacade<T,R> {

    /*
    * 多线程任务构造器:在这里构造所任务信息
    * */
    public  List<R> batchExecute(List<T>task){
        ThreadFacade<T,R> threadService = new ThreadFacadeImpl<T,R>(this,8);
        return threadService.execute(task);
    }

    /*
    * 任务实现器:在这里处理需要执行的任务
    * */
    @Override
    public R execute(T t) {
        return null;
    }
}

--业务调用实现

--1、原来循环代码
List<Object> resultList = new LinkedList<>();
for(Object item:ObjectList){
    
     Object result = ...省略任务执行内容
     resultList.add(result);
}

--2、改造后代码
List<Object> resultList = ThreadTemplate.batchExecute(ObjectList);

改造前:批量审核20份以上报告,耗时都比较久。45份耗时33秒,92份耗时67秒,110份耗时72秒

改造后:100份报告耗时8秒

出错率:0次

四、连接池(web请求和druid组件)

        1)、web请求伪代码       

public static String callWebservcie(String urlKey, String url,String interfaceName,Object[] params) {
		String result = "";
		Client client = null;
		// 创建动态客户端
		JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
		if (!mapHiswebservice.containsKey(urlKey)) {
			client = dcf.createClient(url);
			mapHiswebservice.put(urlKey, client);
		}else{
			client =mapHiswebservice.get(urlKey);
		}
		// 需要密码的情况需要加上用户名和密码
		// client.getOutInterceptors().add(new ClientLoginInterceptor(USER_NAME,
		// PASS_WORD));
		try {
			Object[] resultBacks = client.invoke(interfaceName,params);
			if (resultBacks != null && resultBacks.length > 0) {
				result = resultBacks[0].toString();
			}
		} catch (Exception e) {
			logger.error("原因[{}]异常,异常信息[{}],参数[{}]",
					"Webservice调用异常",
					e.getMessage(),
					JSONArray.toJSON(params),
					e);
			throw new RuntimeException(e);
		}
		return result;
	}

                2)、druid(待更新)

                

primary.datasource.jdbc.type=com.alibaba.druid.pool.DruidDataSource
primary.datasource.jdbc.queryTimeout=15
#tcp/ip配置方式
primary.datasource.jdbc.maximum-pool-size=300
#配置初始化大小、最小、最大
primary.datasource.jdbc.initial-size=5
primary.datasource.jdbc.min-idle=5
primary.datasource.jdbc.max-active=200
#配置获取连接等待超时的时间
primary.datasource.jdbc.max-wait=10000
#配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒。检测时:1.如果连接空闲并且超过minIdle以外的连接,如果空闲时间超过minEvictableIdleTimeMillis设置的值则直接物理关闭。2.在minIdle以内的不处理。
primary.datasource.jdbc.time-between-eviction-runs-millis=60000
#配置一个连接在池中最小生存的时间,单位是毫秒。testWhileIdle为true时,如果连接空闲时间超过minEvictableIdleTimeMillis进行检查,否则不检查;false时,不检查
primary.datasource.jdbc.min-evictable-idle-time-millis=30000
#检验连接是否有效的查询语句
primary.datasource.jdbc.validation-query=SELECT 1
#设置从连接池获取连接时是否检查连接有效性,true时,每次都检查;false时,不检查
primary.datasource.jdbc.test-on-borrow=false
#设置往连接池归还连接时是否检查连接有效性,true时,每次都检查;false时,不检查
primary.datasource.jdbc.test-on-return=false
#设置从连接池获取连接时是否检查连接有效性,true时,如果连接空闲时间超过minEvictableIdleTimeMillis进行检查,否则不检查;false时,不检查
primary.datasource.jdbc.test-while-idle=true
#链接使用超过时间限制是否回收
primary.datasource.jdbc.remove-abandoned=true
#超过时间限制时间(单位秒),目前为5分钟,如果有业务处理时间超过5分钟,可以适当调整。
primary.datasource.jdbc.remove-abandoned-timeout=300

#配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
primary.datasource.filters=stat,wall,log4j

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/495570.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

软件测试 - 测试用例设计方法之等价类划分和边界值分析

1. 等价类划分法 1.1 基本理论 等价类划分法是通过科学的方法找到具有共同特性的测试输入的集合&#xff0c;避免进行穷举测试&#xff0c;大大减少了测试用例的数量&#xff0c;从而提高测试效率。等价类划分法的典型应用场景就是输入框&#xff0c;适用于较少数量输入框的场…

晶振概述及工作原理

晶振在电路板中随处可见&#xff0c;只要用到处理器的地方就必定有晶振的存在&#xff0c;即使没有外部晶振&#xff0c;芯片内部也有晶振。 晶振概述 晶振一般指晶体振荡器。晶体振荡器是指从一块石英晶体上按一定方位角切下薄片&#xff08;简称为晶片&#xff09;&#xf…

虚拟服务器基础架构解决方案:用最小的工作量实现最大的价值

虚拟服务器基础架构解决方案&#xff1a;用最小的工作量实现最大的价值 一切皆可虚拟化&#xff01;包括服务器在内。NetApp 虚拟服务器基础架构解决方案有助于加快数据访问速度、构建创新服务并简化部署&#xff0c;从而实现最大价值。 为什么选择 NetApp 的虚拟服务器基础架…

pytorch矩阵乘法总结

1. element-wise&#xff08;*&#xff09; 按元素相乘&#xff0c;支持广播&#xff0c;等价于torch.mul() a torch.tensor([[1, 2], [3, 4]]) b torch.tensor([[2, 3], [4, 5]]) c a*b # 等价于torch.mul(a,b) # tensor([[ 2, 6], # [12, 20]]) a * torch.tenso…

详解C++类对象(上篇)——超详细

目录 一&#xff0c;面向对象&面向过程的认识(简单了解即可&#xff0c;逐步认识&#xff09; 二&#xff0c; 类 2.1 类的引入 2.2 类的定义 1. struct 2. class 类的两种定义方式&#xff1a; 2.3 封装&类的访问限定符 1. 封装概念 2. 类的访问限定符 …

低代码如何不写代码创建表单和维护表单

工作表新建与修改 新建工作表的流程包含 新建工作表/编辑公祖表为工作表添加字段&#xff0c;例如“员工档案”表中有姓名、性别、年龄等字段为字段设置属性工作表布局工作表预览、保存、关闭 1、新建工作表/修改工作表 新建工作表 修改工作表 2、为工作表添加字段 添加字段 左…

关于C语言的一些杂记2

文章目录 sizeof运算符内容关于基本概念的问题关于一些语句的理解和分号的注意字符的理解关于输出格式的扩展 本文内容摘自C技能树一些优秀的博主 sizeof运算符内容 关于基本概念的问题 sizeof是C语言的关键字&#xff0c;它用来计算变量&#xff08;或数据类型&#xff09;在…

2.Hive创建数据库

1.数据库操作 1.1 创建数据库 create database test comment Just for test location /abcd with dbproperties(aaabbb); comment后面指的是注释&#xff1b;location后面是数据库存放路径&#xff1b;dbproperties代表了数据库的属性 ps.避免要创建的数据库已经存在错误&…

Vue最新状态管理工具Pinia——Pinia的安装与使用

Pinia从了解到实际运用——pinia的安装与使用 知识回调&#xff08;不懂就看这儿&#xff01;&#xff09;场景复现一、环境搭建1.创建项目2.安装pinia 二、基本使用1.创建pinia示例并挂载2.基本使用访问state使用getters使用actions 3.详细示例&#xff08;详细注解&#xff0…

【23】核心易中期刊推荐——视觉/图像感知与识别人工智能算法及应用​​​​​​​

🚀🚀🚀NEW!!!核心易中期刊推荐栏目来啦 ~ 📚🍀 核心期刊在国内的应用范围非常广,核心期刊发表论文是国内很多作者晋升的硬性要求,并且在国内属于顶尖论文发表,具有很高的学术价值。在中文核心目录体系中,权威代表有CSSCI、CSCD和北大核心。其中,中文期刊的数…

2023年盐城工学院五年一贯制专转本旅游学概论考试大纲

2023年盐城工学院五年一贯制专转本旅游学概论考试大纲 一、考核对象 本课程的考核对象是五年一贯制高职专升本酒店管理专业考生。 二、考核方式 本课程考核采用闭卷考试的方式。 三、考核要求 掌握旅游学的基本原理&#xff0c;掌握旅游学的核心概念&#xff0c;具备旅游…

Android性能监控:主循环性能统计LooperStatsService详解

作者&#xff1a;飞起来_飞过来 简介 在Android性能监控和优化领域&#xff0c;一个会影响App性能表现的因素与Handler Message Looper机制有关。当Looper里面的Message处理不及时、或数量太多占用过多处理时间时&#xff0c;可能会出现卡顿感&#xff0c;并且不容易定位到卡顿…

WoShop多商户进口出口跨境电商uniapp商城源码

源码介绍&#xff1a;WoShop多商户跨境电商商城系统将传统的分销、积分、拼团等传统销售模式和直播带货、短视频带货等新型电商营销完美融为一体&#xff0c;专注技术&#xff0c;支持二次开发&#xff0c;专为用户、技术商提供跨境电商技术解决方案。 WoShop跨境电商源码产品…

网络弹性基础知识和实践

什么是网络弹性 弹性是网络处理中断并继续以可接受的标准向用户提供服务的能力。网络运营可能会受到配置错误、断电或操作员错误等问题的威胁。当这种可能性发生时&#xff0c;最终用户无法访问网络&#xff0c;从而对组织产生负面影响。高度弹性的网络可以通过在网络运行中断…

chatgpt官网拒绝访问怎么处理-chatGPT入口正确打开方式

chatgpt官网拒绝访问的原因有哪些 OpenAI是一家人工智能技术公司&#xff0c;其官网是OpenAI最重要的宣传与交流平台之一。但是&#xff0c;有时访问OpenAI官网可能会受到限制或拒绝访问。以下是可能导致OpenAI官网拒绝访问的几个常见原因&#xff1a; IP地址被封锁: OpenAI网…

【Python】只需2行代码,轻松将PDF转换成Word(含示范案例)

文章目录 一、前期准备二、pdf2docx功能三、限制四、案例 一、前期准备 可将 PDF 转换成 docx 文件的 Python 库。该项目通过 PyMuPDF 库提取 PDF 文件中的数据&#xff0c;然后采用 python-docx 库解析内容的布局、段落、图片、表格等&#xff0c;最后自动生成 docx 文件。 …

LFU缓存结构算法

设计LFU缓存结构 LFU&#xff1a;最近最少频率使用 基本思想&#xff1a; 当缓存满时&#xff0c;加入新数据&#xff0c;淘汰缓存中使用次数最少的key&#xff0c;当使用次数最少的key有多个&#xff0c;删除最早调用的key。 定义节点的数据结构 class Node{//使用频率int …

从零开始学习Linux运维,成为IT领域翘楚(八)

文章目录 &#x1f525;Linux进程管理&#x1f525;ps&#x1f525;top&#x1f525;htop &#x1f525;Linux进程管理 &#x1f525;ps 查看系统中所有进程 语法&#xff1a; ps [options] [--help]参数&#xff1a; &#x1f41f; -a 显示所有进程&#xff08;包括其他用…

Windows Server 安装docker

在windows 10 或windows 11 上使用docker&#xff0c;可以直接在docker 官网下载docker desktop安装即可。 但在windows server上则无法支持docker desktop&#xff0c;此时可通过如下方式安装&#xff1a; 以 管理员权限运行Power Shell&#xff0c;然后执行&#xff1a; 安装…

微软骚操作恶心Win10用户,上网得先看广告

IE 浏览器在几个月前被彻底禁用&#xff0c;预装了快30年的老古董也确实到了退役的时候。 而微软也早有准备&#xff0c;2015年随着 Win10 发布推出了 Microsoft Edge 浏览器。 2020年迁移到 Chromium 内核让其成为了主流浏览器之一。 和 Chromium 系其他浏览器一样支持扩展插…