作为后台服务开发,在日常工作中我们天天都在跟数据库打交道,一直在进行各种CRUD操作,都会使用到数据库连接池。按照发展历程,业界知名的数据库连接池有以下几种:c3p0、DBCP、Tomcat JDBC Connection Pool、Druid 等,不过最近最火的是 HiKariCP。
HiKariCP 号称是业界跑得最快的数据库连接池,自从 SpringBoot 2.0 将其作为默认数据库连接池后,其发展势头锐不可当。那它为什么那么快呢?今天咱们就重点聊聊其中的原因。
一、什么是数据库连接池
在讲解HiKariCP之前,我们先简单介绍下什么是数据库连接池(Database Connection Pooling),以及为什么要有数据库连接池。
从根本上而言,数据库连接池和我们常用的线程池一样,都属于池化资源,它在程序初始化时创建一定数量的数据库连接对象并将其保存在一块内存区中。它允许应用程序重复使用一个现有的数据库连接,当需要执行 SQL 时,我们是直接从连接池中获取一个连接,而不是重新建立一个数据库连接,当 SQL 执行完,也并不是将数据库连接真的关掉,而是将其归还到数据库连接池中。我们可以通过配置连接池的参数来控制连接池中的初始连接数、最小连接、最大连接、最大空闲时间等参数,来保证访问数据库的数量在一定可控制的范围类,防止系统崩溃,同时保证用户良好的体验。数据库连接池示意图如下所示:
因此使用数据库连接池的核心作用,就是避免数据库连接频繁创建和销毁,节省系统开销。因为数据库连接是有限且代价昂贵,创建和释放数据库连接都非常耗时,频繁地进行这样的操作将占用大量的性能开销,进而导致网站的响应速度下降,甚至引起服务器崩溃。
二、常见数据库连接池对比分析
这里详细总结了常见数据库连接池的各项功能比较,我们重点分析下当前主流的阿里巴巴Druid与HikariCP,HikariCP在性能上是完全优于Druid连接池的。而Druid的性能稍微差点是由于锁机制的不同,并且Druid提供更丰富的功能,包括监控、sql拦截与解析等功能,两者的侧重点不一样,HikariCP追求极致的高性能。
下面是官网提供的性能对比图,在性能上面这五种数据库连接池的排序如下:HikariCP>druid>tomcat-jdbc>dbcp>c3p0:
三、HikariCP 数据库连接池简介
HikariCP 号称是史上性能最好的数据库连接池,SpringBoot 2.0将它设置为默认的数据源连接池。Hikari相比起其它连接池的性能高了非常多,那么,这是怎么做到的呢?通过查看HikariCP官网介绍,对于HikariCP所做优化总结如下:
1. 字节码精简 : 优化代码,编译后的字节码量极少,使得CPU缓存可以加载更多的程序代码;
HikariCP在优化并精简字节码上也下了功夫,使用第三方的Java字节码修改类库Javassist来生成委托实现动态代理.动态代理的实现在ProxyFactory类,速度更快,相比于JDK Proxy生成的字节码更少,精简了很多不必要的字节码。
2. 优化代理和拦截器: 减少代码,例如HikariCP的Statement proxy只有100行代码,只有BoneCP的十分之一;
3. 自定义数组类型(FastStatementList)代替ArrayList: 避免ArrayList每次get()都要进行range check,避免调用remove()时的从头到尾的扫描(由于连接的特点是后获取连接的先释放);
4. 自定义集合类型(ConcurrentBag): 提高并发读写的效率;
5. 其他针对BoneCP缺陷的优化 ,比如对于耗时超过一个CPU时间片的方法调用的研究。
当然作为一个数据库连接池,不能说快就会被消费者所推崇,它还具有非常好的健壮性及稳定性。HikariCP从15年推出以来,已经经受了广大应用市场的考验,并且成功地被SpringBoot2.0作为默认数据库连接池进行推广,在可靠性上面是值得信任的。其次借助于其代码量少,占用cpu和内存量小的优点,使得它的执行率非常高。最后,Spring配置HikariCP和druid基本没什么区别,迁移过来非常方便,这些都是为什么HikariCP目前如此受欢迎的原因。
字节码精简、优化代理和拦截器、自定义数组类型。
四、HikariCP 核心源码解析
4.1 FastList 是如何优化性能问题的
首先我们来看一下执行数据库操作规范化的操作步骤:
通过数据源获取一个数据库连接;
创建 Statement;
执行 SQL;
通过 ResultSet 获取 SQL 执行结果;
释放 ResultSet;
释放 Statement;
释放数据库连接。
当前所有数据库连接池都是严格地根据这个顺序来进行数据库操作的,为了防止最后的释放操作,各类数据库连接池都会把创建的 Statement 保存在数组 ArrayList 里,来保证当关闭连接的时候,可以依次将数组中的所有 Statement 关闭。HiKariCP 在处理这一步骤中,认为 ArrayList 的某些方法操作存在优化空间,因此对List接口的精简实现,针对List接口中核心的几个方法进行优化,其他部分与ArrayList基本一致 。
首先是get()方法,ArrayList每次调用get()方法时都会进行rangeCheck检查索引是否越界,FastList的实现中去除了这一检查,是因为数据库连接池满足索引的合法性,能保证不会越界,此时rangeCheck就属于无效的计算开销,所以不用每次都进行越界检查。省去频繁的无效操作,可以明显地减少性能消耗。
public T get(int index)
{
// ArrayList 在此多了范围检测 rangeCheck(index);
return elementData[index];
}
其次是remove方法,当通过 conn.createStatement() 创建一个 Statement 时,需要调用 ArrayList 的 add() 方法加入到 ArrayList 中,这个是没有问题的;但是当通过 stmt.close() 关闭 Statement 的时候,需要调用 ArrayList 的 remove() 方法来将其从 ArrayList 中删除,而ArrayList的remove(Object)方法是从头开始遍历数组,而FastList是从数组的尾部开始遍历,因此更为高效。假设一个 Connection 依次创建 6 个 Statement,分别是 S1、S2、S3、S4、S5、S6,而关闭 Statement 的顺序一般都是逆序的,从S6 到 S1,而 ArrayList 的 remove(Object o) 方法是顺序遍历查找,逆序删除而顺序查找,这样的查找效率就太慢了。因此FastList对其进行优化,改成了逆序查找。如下代码为FastList 实现的数据移除操作,相比于ArrayList的 remove()代码, FastList 去除了检查范围 和 从头到尾遍历检查元素的步骤,其性能更快。
public boolean remove(Object element)
{
// 删除操作使用逆序查找
for (int index = size - 1; index >= 0; index--) {
if (element == elementData[index]) {
final int numMoved = size - index - 1;
// 如果角标不是最后一个,复制一个新的数组结构
if (numMoved > 0) {
System.arraycopy(elementData, index + 1, elementData, index, numMoved);
}
//如果角标是最后面的 直接初始化为null
elementData[--size] = null;
return true;
}
}
return false;
}
通过上述源码分析,FastList 的优化点还是很简单的。相比ArrayList仅仅是去掉了rage检查,扩容优化等细节处,删除时数组从后往前遍历查找元素等微小的调整,从而追求性能极致。当然FastList 对于 ArrayList 的优化,我们不能说ArrayList不好。所谓定位不同、追求不同,ArrayList作为通用容器,更追求安全、稳定,操作前rangeCheck检查,对非法请求直接抛出异常,更符合 fail-fast(快速失败)机制,而FastList追求的是性能极致。
下面我们再来聊聊 HiKariCP 中的另外一个数据结构 ConcurrentBag,看看它又是如何提升性能的。
4.2 ConcurrentBag 实现原理分析
当前主流数据库连接池实现方式,大都用两个阻塞队列来实现。一个用于保存空闲数据库连接的队列 idle,另一个用于保存忙碌数据库连接的队列 busy;获取连接时将空闲的数据库连接从 idle 队列移动到 busy 队列,而关闭连接时将数据库连接从 busy 移动到 idle。这种方案将并发问题委托给了阻塞队列,实现简单,但是性能并不是很理想。因为 Java SDK 中的阻塞队列是用锁实现的,而高并发场景下锁的争用对性能影响很大。
HiKariCP 并没有使用 Java SDK 中的阻塞队列,而是自己实现了一个叫做 ConcurrentBag 的并发容器,在连接池(多线程数据交互)的实现上具有比LinkedBlockingQueue和LinkedTransferQueue更优越的性能。
ConcurrentBag 中最关键的属性有 4 个,分别是:用于存储所有的数据库连接的共享队列 sharedList、线程本地存储 threadList、等待数据库连接的线程数 waiters 以及分配数据库连接的工具 handoffQueue。其中,handoffQueue 用的是 Java SDK 提供的 SynchronousQueue,SynchronousQueue 主要用于线程之间传递数据。
// 存放共享元素,用于存储所有的数据库连接
private final CopyOnWriteArrayList sharedList;
// 在 ThreadLocal 缓存线程本地的数据库连接,避免线程争用
private final ThreadLocal> threadList;
// 等待数据库连接的线程数
private final AtomicInteger waiters;
// 接力队列,用来分配数据库连接
private final SynchronousQueue handoffQueue;
ConcurrentBag 保证了全部的资源均只能通过 add() 方法进行添加,当线程池创建了一个数据库连接时,通过调用 ConcurrentBag 的 add() 方法加入到 ConcurrentBag 中,并通过 remove() 方法进行移出。下面是 add() 方法和 remove() 方法的具体实现,添加时实现了将这个连接加入到共享队列 sharedList 中,如果此时有线程在等待数据库连接,那么就通过 handoffQueue 将这个连接分配给等待的线程。
public void add(final T bagEntry)
{
if (closed) {
LOGGER.info("ConcurrentBag has been closed, ignoring add()");
throw new IllegalStateException("ConcurrentBag has been closed, ignoring add()");
}
// 新添加的资源优先放入sharedList
sharedList.add(bagEntry);
// 当有等待资源的线程时,将资源交到等待线程 handoffQueue 后才返回
while (waiters.get() > 0 && bagEntry.getState() == STATE_NOT_IN_USE && !handoffQueue.offer(bagEntry)) {
yield();
}
}
public boolean remove(final T bagEntry)
{
// 如果资源正在使用且无法进行状态切换,则返回失败
if (!bagEntry.compareAndSet(STATE_IN_USE, STATE_REMOVED) && !bagEntry.compareAndSet(STATE_RESERVED, STATE_REMOVED) && !closed) {
LOGGER.warn("Attempt to remove an object from the bag that was not borrowed or reserved: {}", bagEntry);
return false;
}
// 从sharedList中移出
final boolean removed = sharedList.remove(bagEntry);
if (!removed && !closed) {
LOGGER.warn("Attempt to remove an object from the bag that does not exist: {}", bagEntry);
}
return removed;
}
同时ConcurrentBag通过提供的 borrow() 方法来获取一个空闲的数据库连接,并通过requite()方法进行资源回收,borrow() 的主要逻辑是:
查看线程本地存储 threadList 中是否有空闲连接,如果有,则返回一个空闲的连接;
如果线程本地存储中无空闲连接,则从共享队列 sharedList 中获取;
如果共享队列中也没有空闲的连接,则请求线程需要等待。
// 该方法会从连接池中获取连接, 如果没有连接可用, 会一直等待timeout超时
public T borrow(long timeout, final TimeUnit timeUnit) throws InterruptedException
{
// 首先查看线程本地资源threadList是否有空闲连接
final List list = threadList.get();
// 从后往前反向遍历是有好处的, 因为最后一次使用的连接, 空闲的可能性比较大, 之前的连接可能会被其他线程提前借走了
for (int i = list.size() - 1; i >= 0; i--) {
final Object entry = list.remove(i);
@SuppressWarnings("unchecked")
final T bagEntry = weakThreadLocals ? ((WeakReference) entry).get() : (T) entry;
// 线程本地存储中的连接也可以被窃取, 所以需要用CAS方法防止重复分配
if (bagEntry != null && bagEntry.compareAndSet(STATE_NOT_IN_USE, STATE_IN_USE)) {
return bagEntry;
}
}
// 当无可用本地化资源时,遍历全部资源,查看可用资源,并用CAS方法防止资源被重复分配
final int waiting = waiters.incrementAndGet();
try {
for (T bagEntry : sharedList) {
if (bagEntry.compareAndSet(STATE_NOT_IN_USE, STATE_IN_USE)) {
// 因为可能“抢走”了其他线程的资源,因此提醒包裹进行资源添加
if (waiting > 1) {
listener.addBagItem(waiting - 1);
}
return bagEntry;
}
}
listener.addBagItem(waiting);
timeout = timeUnit.toNanos(timeout);
do {
final long start = currentTime();
// 当现有全部资源都在使用中时,等待一个被释放的资源或者一个新资源
final T bagEntry = handoffQueue.poll(timeout, NANOSECONDS);
if (bagEntry == null || bagEntry.compareAndSet(STATE_NOT_IN_USE, STATE_IN_USE)) {
return bagEntry;
}
timeout -= elapsedNanos(start);
} while (timeout > 10_000);
return null;
}
finally {
waiters.decrementAndGet();
}
}
public void requite(final T bagEntry)
{
// 将资源状态转为未在使用
bagEntry.setState(STATE_NOT_IN_USE);
// 判断是否存在等待线程,若存在,则直接转手资源
for (int i = 0; waiters.get() > 0; i++) {
if (bagEntry.getState() != STATE_NOT_IN_USE || handoffQueue.offer(bagEntry)) {
return;
}
else if ((i & 0xff) == 0xff) {
parkNanos(MICROSECONDS.toNanos(10));
}
else {
yield();
}
}
// 否则,进行资源本地化处理
final List threadLocalList = threadList.get();
if (threadLocalList.size() < 50) {
threadLocalList.add(weakThreadLocals ? new WeakReference<>(bagEntry) : bagEntry);
}
}
borrow() 方法可以说是整个 HikariCP 中最核心的方法,它是我们从连接池中获取连接的时候最终会调用到的方法。需要注意的是 borrow() 方法只提供对象引用,不移除对象,因此使用时必须通过 requite() 方法进行放回,否则容易导致内存泄露。requite() 方法首先将数据库连接状态改为未使用,之后查看是否存在等待线程,如果有则分配给等待线程;否则将该数据库连接保存到线程本地存储里。
ConcurrentBag 实现采用了queue-stealing的机制获取元素:首先尝试从ThreadLocal中获取属于当前线程的元素来避免锁竞争,如果没有可用元素则再次从共享的CopyOnWriteArrayList中获取。此外,ThreadLocal和CopyOnWriteArrayList在ConcurrentBag中都是成员变量,线程间不共享,避免了伪共享(false sharing)的发生。同时因为线程本地存储中的连接是可以被其他线程窃取的,在共享队列中获取空闲连接,所以需要用 CAS 方法防止重复分配。
五、总结
Hikari 作为 SpringBoot2.0默认的连接池,目前在行业内使用范围非常广,对于大部分业务来说,都可以实现快速接入使用,做到高效连接。
参考资料
https://github.com/brettwooldridge/HikariCP
https://github.com/alibaba/druid
作者:vivo 游戏技术团队
你可能感兴趣的:(技术干货,数据库,SpringBoot,HikariCP,ThreadLocal)
Perf-linux服务器性能测试
进阶的小猫
压测和性能测试 linux 运维 python
1.压测基础数据准备:压测的环境:2.压测时关注服务端性能内存:50%以下CPU:一般小于75%,平均每核CPU的load小于1网络带宽:磁盘:IO:数据库:JVM:小于80%fullGC频率:小于半小时一次响应时间:小于期望值20,30,50,100ms错误率:低于0.5‰如何做服务器压测-入门级-简书https://www.jianshu.com/p/0b1f2f3b4bbd实现一个简单的压测
SQLAlchemy 介绍与实践
cliffordl
python python 数据库
postgresql实践pydantic实践1.SQLAlchemy介绍SQLAlchemy是一个ORM框架。SQLAlchemy是一个用于Python的SQL工具和对象关系映射(ORM)库。它允许你通过Python代码来与关系型数据库交互,而不必直接编写SQL语句。简单介绍一下对象关系映射吧,对象关系映射(英语:ObjectRelationalMapping,简称ORM,或O/RM,或O/Rma
FastDFS实用笔记 (Docker 搭建环境 + 整合 SpringBoot)
字节全栈_kYu
笔记 docker spring boot
解决了大容量存储和负载均衡的问题,特别适合中小文件(4KB>文件路径为空…”);return“文件路径不能为空”;}try{StorePathstorePath=StorePath.parseFromUrl(fileUrl);storageClient.deleteFile(storePath.getGroup(),storePath.getPath());}catch(Exceptione){l
2025最新版Java面试八股文大全
m0_74823452
java 面试 开发语言
一、Java并发面试题1、ThreadLocal1.1谈谈你对ThreadLocal的理解?ThreadLocal的作用主要是做数据隔离,填充的数据只属于当前线程,变量的数据对别的线程而言是相对隔离的。它不是针对程序的全局变量,只是针对当前线程的全局变量。1.2ThreadLocal底层实现原理?Threadlocal内部有一个非常关键的内部类ThreadlocalMap,里面定义了一个由key-
MySQL与Python:连接与操作数据库的魔法之旅
墨瑾轩
一起学学数据库【一】 数据库 mysql
关注墨瑾轩,带你探索编程的奥秘!超萌技术攻略,轻松晋级编程高手技术宝库已备好,就等你来挖掘订阅墨瑾轩,智趣学习不孤单即刻启航,编程之旅更有趣开篇:数据库世界的探险️嘿,亲爱的Python小巫师们!今天我们要一起踏上一段探险之旅——连接并操作MySQL数据库。在这个数据的海洋中,MySQL是我们的宝藏库,而Python则是我们的魔法棒。准备好你的魔法帽,我们即将开始这段连接与操作数据库的魔法之旅!M
数据库备份与恢复--mysqldump+binlog增量备份
一只懵懂得小猿
数据库运维 数据库
一、前提:开启bin-log修改配置文件vim/etc/my.cnf[mysqld]log_bin=mysql-binserver_id=31122--注意此处server_id要独立,建议使用IP地址后几位重启mysqld:systemctlrestartmysqld二、mysqldump+binlog当在完全备份后,由于操作失误将数据遗失而未来得及备份时使用binlog日志进行恢复当失误出现后
MongoDB深度解析与实践案例
我的运维人生
mongodb 数据库 运维开发 技术共享
MongoDB深度解析与实践案例在当今大数据盛行的时代,NoSQL数据库以其灵活的数据模型和水平扩展能力,成为了众多应用场景下的首选。MongoDB,作为NoSQL数据库的领军者之一,凭借其面向文档的存储方式、强大的查询功能以及丰富的生态系统,在众多领域大放异彩。本文将从MongoDB的基本概念出发,深入探讨其核心特性,并通过一个实际案例展示如何在项目中高效使用MongoDB。一、MongoDB基
SpringBoot核心组件详细解析
德乐懿
后端 spring boot 后端 java
SpringBoot核心组件详细解析SpringBoot作为当前Java领域最流行的微服务框架之一,其核心组件的设计与应用对于开发高效、稳定的应用程序至关重要。本文将详细解析SpringBoot的核心组件,包括SpringBoot框架本身、Spring、SpringMVC、数据库连接池等,通过阐述每个组件的作用、特点、使用场景,并结合实际案例,深入分析SpringBoot核心组件之间的关联性和依赖
什么是ThreadLocal的上下文丢失问题?
LUCIAZZZ
java jvm 开发语言 spring boot juc 多线程
什么情况下发生上下文丢失异步操作(如使用CompletableFuture或回调或线程池):在多线程异步任务处理中,如果一个线程执行异步任务时使用了ThreadLocal,并且该任务在另一个线程中继续执行(例如,线程A创建了一个异步任务,线程B执行了该任务),那么ThreadLocal中存储的上下文信息可能不会传递到线程B,导致上下文丢失解决方案1.使用InheritableThreadLocal
【TiDB系列文章】PD(Placement Driver)
学弟Craze
TiDB tidb 数据库
引言在分布式数据库的生态系统中,PD扮演着至关重要的角色。作为TiDB的核心组件之一,PD负责数据的放置和调度,确保数据的高可用性和负载均衡。本文将详细介绍PD的功能、架构以及它在TiDB中的作用。PD概述PD是TiDB分布式数据库中的元信息管理组件,负责存储集群的元信息和调度数据。它相当于分布式数据库的“大脑”,负责整个集群的数据分布和负载均衡。PD通过合理的调度策略,确保数据均匀分布在集群中,
(尚硅谷 Java 学习 B 站大学版)Day 13 面向对象 方法
亢从文_Jackson
java 学习 开发语言
4-5类的成员之二:方法(Method)一、“万事万物皆对象”**:(理解)1、在Java语言范畴中,我们都将功能、结构等封装到类中,通过类的实例化,来调用具体的功能结构>Scanner,String等>文件:File>网络资源:URL2、涉及到java语言与前端html、后端数据库交互时,前后端的结构在Java层面交互时,都体现为类、对象二、内存解析说明1、引用类型的变量,只可能存储两类值:nu
Bun:快速、现代的Go语言替代工具链
廉欣盼Industrious
Bun:快速、现代的Go语言替代工具链bunuptrace/bun:是一个基于Rust的SQL框架,它支持PostgreSQL、MySQL、SQLite3等多种数据库。适合用于构建高性能、可扩展的Web应用程序,特别是对于需要使用Rust语言和SQL数据库的场景。特点是Rust语言、高性能、可扩展、支持多种数据库。项目地址:https://gitcode.com/gh_mirrors/bun/bu
探索数据库交互新境界:Rustorm,以Rust之力重塑ORM新篇章
马兰菲
探索数据库交互新境界:Rustorm,以Rust之力重塑ORM新篇章old-rustormAnORMforrust项目地址:https://gitcode.com/gh_mirrors/ol/old-rustorm在现代软件开发的洪流中,一款高效、灵活且易于理解的ORM(对象关系映射)框架,无疑是连接应用程序与数据库之间的桥梁。今日,让我们一同探索基于Rust编程语言的明星项目——Rustorm,
如何在springboot中合理使用工厂模式(你真的会在实际业务中应用设计模式吗?)
辞半夏丶北笙
spring boot 设计模式 后端
如何在springboot中合理使用工厂模式-工厂模式工厂模式优点:前言请看如下工程结构实例:1、在工厂中声明的bean如何交给springboot管理方法一:使用Spring的@Bean方法来注册工厂方法方法二:使用Spring的ApplicationContext来获取bean方法三:使用原型bean(推荐)实现代码1、定义组件接口:2、不同的组件实现:3、创建工厂通过抽象工厂注入不同的bea
MyBatis:深入了解其特性与优势
HelloZheQ
mybatis
MyBatis是一款优秀的持久层框架,它通过XML或注解的方式将Java对象映射到数据库表,简化了数据库操作。相比于其他ORM框架,MyBatis更加灵活、轻量级,并且提供了更细粒度的SQL控制。本文将深入探讨MyBatis的特点和优势,帮助你更好地理解和使用它。MyBatis的核心特性SQL映射:定义:MyBatis的核心功能是将Java对象和SQL语句进行映射。这意味着你可以直接编写SQL语句
Web 开发入门:从前端到后端的全栈开发探索
HelloZheQ
前端
Web开发是指创建和维护通过网络浏览器访问的应用程序。Web开发涉及到的领域非常广泛,涵盖了前端、后端、数据库等多个技术栈。在这篇文章中,我们将详细介绍Web开发的基本概念、前端和后端的技术、全栈开发的特点以及如何开始从事Web开发。1.Web开发简介Web开发是构建和维护网站或Web应用程序的过程,分为前端开发、后端开发和全栈开发。前端开发负责用户界面和交互体验,后端开发负责服务器端的逻辑处理、
Elasticsearch与数据库数据一致性:最佳实践与解决方案
HelloZheQ
elasticsearch 数据库 jenkins
在现代应用程序中,Elasticsearch(ES)作为一个高效的分布式搜索引擎,常常与数据库一同使用,以提供强大的搜索、分析和数据可视化功能。然而,数据库和Elasticsearch之间的同步与一致性常常成为一个挑战。如何确保在数据库中进行的每一次操作(如插入、更新和删除)都能正确地反映到Elasticsearch中?如何处理两者之间的数据一致性问题?本文将介绍如何保持Elasticsearch
Kafka中文文档
圣心
kafka 分布式
文章来源:https://kafka.cadn.net.cn什么是事件流式处理?事件流是人体中枢神经系统的数字等价物。它是为“永远在线”的世界奠定技术基础,在这个世界里,企业越来越多地使用软件定义和automated,而软件的用户更多的是Software。从技术上讲,事件流式处理是从事件源实时捕获数据的做法如数据库、传感器、移动设备、云服务和流形式的软件应用程序事件;持久存储这些事件流以供以后检索
DBeaver连接MySQL提示Access denied for user ‘‘@‘ip‘ (using password: YES)的解决方法
lingllllove
mysql tcp/ip adb
在使用DBeaver连接MySQL数据库时,如果遇到“Accessdeniedforuser''@'ip'(usingpassword:YES)”的错误提示,说明用户认证失败。此问题通常与数据库用户权限、配置错误或网络设置有关。本文将详细介绍解决此问题的步骤。一、检查用户名和密码首先,确保在DBeaver中输入的用户名和密码是正确的。验证步骤如下:打开DBeaver,选择对应的数据库连接。检查连接
使用 Docker(Podman) 部署 MongoDB 数据库及使用详解
特立独行的猫a
Go语言实践笔记 数据库 docker podman
在现代开发环境中,容器化技术(如Docker和Podman)已成为部署和管理应用程序的标准方式。本文将详细介绍如何使用Podman/Docker部署MongoDB数据库,并确保其他应用程序容器能够通过Docker网络成功连接到MongoDB。我们将逐步解决常见的问题,如权限配置和认证设置,应用容器如何连接和使用容器中的MongoDB数据库等。选择Podman而不是Docker为什么选择Podman
基于Spring Boot的校园志愿者服务网站
超级无敌暴龙战士塔塔开
Java课设与毕设资源 spring boot java 后端
文章目录项目介绍主要功能截图:登录个人中心志愿者管理活动类型管理活动报名管理活动心得部分代码展示设计总结项目获取方式作者主页:Java韩立简介:Java领域优质创作者、简历模板、学习资料、面试题库【关注我,都给你】文末获取源码联系项目介绍校园志愿者服务网站,java项目,springboot项目。eclipse和idea都能打开运行。推荐环境配置:eclipse/ideajdk1.8mavenmy
Java学习教程,从入门到精通,JDBC中WHERE子句的语法知识点及案例代码(107)
知识分享小能手
大数据 Java 编程语言如门 java 学习 开发语言 数据库 大数据 JDBC intellij-idea
JDBC中WHERE子句的语法知识点及案例代码JDBCWHERE子句语法知识点WHERE子句用于在SQL查询中对数据进行筛选,它可以根据指定的条件过滤数据行。在JDBC中,WHERE子句通常用于SELECT、UPDATE和DELETE语句中。常见的WHERE子句条件比较运算符=:等于:大于=:大于等于18ANDscore>=80";try{//加载数据库驱动Class.forName("com.m
SpringBoot核心特性:自动配置与起步依赖
YY...yy
SpringBoot框架学习 spring boot java spring
前言SpringBoot通过一系列创新的设计和特性,极大地简化了Spring应用的开发和配置工作。其中,自动配置(Auto-Configuration)和起步依赖(Starter)是SpringBoot最为核心的功能之一。这两项特性不仅降低了开发者的入门门槛,还显著提升了开发效率。一、SpringBoot的核心优势:零配置与自动化SpringBoot的最大魅力在于它能够最大限度地减少开发者的手动配
携程Android开发面试题及参考答案
大模型大数据攻城狮
android android面经 RN原理 android动画 kotlin okhttp 异步请求
在项目中,给别人发的动态点赞功能是如何实现的?数据库设计:首先要在数据库中为动态表添加一个点赞字段,用于记录点赞数量,同时可能需要一个点赞关系表,记录用户与动态之间的点赞关联,包括点赞时间等信息。界面交互:在Android界面上,为点赞按钮设置点击事件监听器。当用户点击点赞按钮时,按钮状态改变,比如从未点赞的图标变为已点赞的图标。网络请求:通过网络框架如Retrofit等,向服务器发送点赞请求,请
Spring Boot 配置文件详解:YAML vs Properties
YY...yy
SpringBoot框架学习 spring boot java 前端
前言在SpringBoot开发中,配置文件是应用运行的核心。无论是开发、测试还是生产环境,配置文件都起到了至关重要的作用。SpringBoot提供了两种主流的配置文件格式:Properties和YAML。它们各有特点,适用于不同的场景。本文将从以下几个方面详细解析SpringBoot的配置文件:YAML和Properties的区别与使用场景多环境配置:管理开发、测试、生产环境的不同设置自定义配置:
LSM-Tree 与 RocksDB
波哥在路上
RocksDB RocksDB
冥冥之中,接触到了不同于关系数据库的NoSQLKey-Value存储引擎RocksDB,懵懵懂懂、充满好奇,google一点,满眼皆是LSM-Tree,头晕眼花、若即若离,便有了这篇文章,一起与大家分享这趟探险之旅。LSM-Tree(Log-Structured-Merge-Tree)LSM从命名上看,容易望文生义成一个具体的数据结构,一个tree。但LSM并不是一个具体的数据结构,也不是一个tr
eclipse报错:java.lang.ClassNotFoundException: com.mysql.cj.jdbc.Driver
夏末秋也凉
WEB eclipse
驱动版本不一致,//MySQL8.0以下版本-JDBC驱动名及数据库URLstaticfinalStringJDBC_DRIVER="com.mysql.jdbc.Driver";staticfinalStringDB_URL="jdbc:mysql://localhost:3306/RUNOOB";//MySQL8.0以上版本-JDBC驱动名及数据库URLstaticfinalStringJDB
分库分表后如何进行join操作
fajianchen
IT架构 系统设计 sql 分库分表
在分库分表后的系统中,进行表之间的JOIN操作比在单一数据库表中复杂得多,因为涉及的数据可能位于不同的物理节点或分片中。此时,传统的SQLJOIN语句不能直接用于不同分片的数据,以下是几种处理这样的跨分片JOIN操作的方法:方法1:应用程序层JOIN分步查询:在应用程序中,先查询一个分片中的数据(如,获取第一个表的数据)。对于那些需要JOIN的数据,使用这些结果的数据再去另一个分片中查询。内存合并
Python Web框架比较:Flask与FastAPI的特性和应用场景
不一样的信息安全
node.js
摘要本文探讨Python语言中的两大Web框架:Flask和FastAPI。Flask以轻量级和易用性著称,提供高度灵活性,允许开发者自由选择数据库、表单验证库等工具。其核心架构简洁,借助丰富的扩展可显著增强功能。FastAPI则专注于高性能与现代Web开发需求,支持异步编程,具备自动交互式API文档生成功能。两者各具特色,适合不同应用场景。关键词Python语言,Web框架,Flask特性,Fa
mysql索引结构
Qzer_407
# MySQL 后端技术栈 mysql 数据库
多种数据结构在数据库索引领域,特别是MySQL的InnoDB存储引擎中,聚簇索引(ClusteredIndex)和非聚簇索引(也称为二级索引,SecondaryIndex)是两种主要的索引类型。这些索引类型在数据结构的选择上有所不同,而Hash结构、二叉搜索树(BST)、AVL树、B-Tree、B+Tree和R-Tree是常见的索引数据结构。下面我将对这些数据结构进行类比,并特别关注它们在Inno
分享100个最新免费的高匿HTTP代理IP
mcj8089
代理IP 代理服务器 匿名代理 免费代理IP 最新代理IP
推荐两个代理IP网站:
1. 全网代理IP:http://proxy.goubanjia.com/
2. 敲代码免费IP:http://ip.qiaodm.com/
120.198.243.130:80,中国/广东省
58.251.78.71:8088,中国/广东省
183.207.228.22:83,中国/
mysql高级特性之数据分区
annan211
java 数据结构 mongodb 分区 mysql
mysql高级特性
1 以存储引擎的角度分析,分区表和物理表没有区别。是按照一定的规则将数据分别存储的逻辑设计。器底层是由多个物理字表组成。
2 分区的原理
分区表由多个相关的底层表实现,这些底层表也是由句柄对象表示,所以我们可以直接访问各个分区。存储引擎管理分区的各个底层
表和管理普通表一样(所有底层表都必须使用相同的存储引擎),分区表的索引只是
JS采用正则表达式简单获取URL地址栏参数
chiangfai
js 地址栏参数获取
GetUrlParam:function GetUrlParam(param){
var reg = new RegExp("(^|&)"+ param +"=([^&]*)(&|$)");
var r = window.location.search.substr(1).match(reg);
if(r!=null
怎样将数据表拷贝到powerdesigner (本地数据库表)
Array_06
powerDesigner
==================================================
1、打开PowerDesigner12,在菜单中按照如下方式进行操作
file->Reverse Engineer->DataBase
点击后,弹出 New Physical Data Model 的对话框
2、在General选项卡中
Model name:模板名字,自
logbackのhelloworld
飞翔的马甲
日志 logback
一、概述
1.日志是啥?
当我是个逗比的时候我是这么理解的:log.debug()代替了system.out.print();
当我项目工作时,以为是一堆得.log文件。
这两天项目发布新版本,比较轻松,决定好好地研究下日志以及logback。
传送门1:日志的作用与方法:
http://www.infoq.com/cn/articles/why-and-how-log
上面的作
新浪微博爬虫模拟登陆
随意而生
新浪微博
转载自:http://hi.baidu.com/erliang20088/item/251db4b040b8ce58ba0e1235
近来由于毕设需要,重新修改了新浪微博爬虫废了不少劲,希望下边的总结能够帮助后来的同学们。
现行版的模拟登陆与以前相比,最大的改动在于cookie获取时候的模拟url的请求
synchronized
香水浓
java thread
Java语言的关键字,可用来给对象和方法或者代码块加锁,当它锁定一个方法或者一个代码块的时候,同一时刻最多只有一个线程执行这段代码。当两个并发线程访问同一个对象object中的这个加锁同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。然而,当一个线程访问object的一个加锁代码块时,另一个线程仍然
maven 简单实用教程
AdyZhang
maven
1. Maven介绍 1.1. 简介 java编写的用于构建系统的自动化工具。目前版本是2.0.9,注意maven2和maven1有很大区别,阅读第三方文档时需要区分版本。 1.2. Maven资源 见官方网站;The 5 minute test,官方简易入门文档;Getting Started Tutorial,官方入门文档;Build Coo
Android 通过 intent传值获得null
aijuans
android
我在通过intent 获得传递兑现过的时候报错,空指针,我是getMap方法进行传值,代码如下 1 2 3 4 5 6 7 8 9
public
void
getMap(View view){
Intent i =
apache 做代理 报如下错误:The proxy server received an invalid response from an upstream
baalwolf
response
网站配置是apache+tomcat,tomcat没有报错,apache报错是:
The proxy server received an invalid response from an upstream server. The proxy server could not handle the request GET /. Reason: Error reading fr
Tomcat6 内存和线程配置
BigBird2012
tomcat6
1、修改启动时内存参数、并指定JVM时区 (在windows server 2008 下时间少了8个小时)
在Tomcat上运行j2ee项目代码时,经常会出现内存溢出的情况,解决办法是在系统参数中增加系统参数:
window下, 在catalina.bat最前面
set JAVA_OPTS=-XX:PermSize=64M -XX:MaxPermSize=128m -Xms5
Karam与TDD
bijian1013
Karam TDD
一.TDD
测试驱动开发(Test-Driven Development,TDD)是一种敏捷(AGILE)开发方法论,它把开发流程倒转了过来,在进行代码实现之前,首先保证编写测试用例,从而用测试来驱动开发(而不是把测试作为一项验证工具来使用)。
TDD的原则很简单:
a.只有当某个
[Zookeeper学习笔记之七]Zookeeper源代码分析之Zookeeper.States
bit1129
zookeeper
public enum States {
CONNECTING, //Zookeeper服务器不可用,客户端处于尝试链接状态
ASSOCIATING, //???
CONNECTED, //链接建立,可以与Zookeeper服务器正常通信
CONNECTEDREADONLY, //处于只读状态的链接状态,只读模式可以在
【Scala十四】Scala核心八:闭包
bit1129
scala
Free variable A free variable of an expression is a variable that’s used inside the expression but not defined inside the expression. For instance, in the function literal expression (x: Int) => (x
android发送json并解析返回json
ronin47
android
package com.http.test;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import
一份IT实习生的总结
brotherlamp
PHP php资料 php教程 php培训 php视频
今天突然发现在不知不觉中自己已经实习了 3 个月了,现在可能不算是真正意义上的实习吧,因为现在自己才大三,在这边撸代码的同时还要考虑到学校的功课跟期末考试。让我震惊的是,我完全想不到在这 3 个月里我到底学到了什么,这是一件多么悲催的事情啊。同时我对我应该 get 到什么新技能也很迷茫。所以今晚还是总结下把,让自己在接下来的实习生活有更加明确的方向。最后感谢工作室给我们几个人这个机会让我们提前出来
据说是2012年10月人人网校招的一道笔试题-给出一个重物重量为X,另外提供的小砝码重量分别为1,3,9。。。3^N。 将重物放到天平左侧,问在两边如何添加砝码
bylijinnan
java
public class ScalesBalance {
/**
* 题目:
* 给出一个重物重量为X,另外提供的小砝码重量分别为1,3,9。。。3^N。 (假设N无限大,但一种重量的砝码只有一个)
* 将重物放到天平左侧,问在两边如何添加砝码使两边平衡
*
* 分析:
* 三进制
* 我们约定括号表示里面的数是三进制,例如 47=(1202
dom4j最常用最简单的方法
chiangfai
dom4j
要使用dom4j读写XML文档,需要先下载dom4j包,dom4j官方网站在 http://www.dom4j.org/目前最新dom4j包下载地址:http://nchc.dl.sourceforge.net/sourceforge/dom4j/dom4j-1.6.1.zip
解开后有两个包,仅操作XML文档的话把dom4j-1.6.1.jar加入工程就可以了,如果需要使用XPath的话还需要
简单HBase笔记
chenchao051
hbase
一、Client-side write buffer 客户端缓存请求 描述:可以缓存客户端的请求,以此来减少RPC的次数,但是缓存只是被存在一个ArrayList中,所以多线程访问时不安全的。 可以使用getWriteBuffer()方法来取得客户端缓存中的数据。 默认关闭。 二、Scan的Caching 描述: next( )方法请求一行就要使用一次RPC,即使
mysqldump导出时出现when doing LOCK TABLES
daizj
mysql mysqdump 导数据
执行 mysqldump -uxxx -pxxx -hxxx -Pxxxx database tablename > tablename.sql
导出表时,会报
mysqldump: Got error: 1044: Access denied for user 'xxx'@'xxx' to database 'xxx' when doing LOCK TABLES
解决
CSS渲染原理
dcj3sjt126com
Web
从事Web前端开发的人都与CSS打交道很多,有的人也许不知道css是怎么去工作的,写出来的css浏览器是怎么样去解析的呢?当这个成为我们提高css水平的一个瓶颈时,是否应该多了解一下呢?
一、浏览器的发展与CSS
《阿甘正传》台词
dcj3sjt126com
Part Ⅰ:
《阿甘正传》Forrest Gump经典中英文对白
Forrest: Hello! My names Forrest. Forrest Gump. You wanna Chocolate? I could eat about a million and a half othese. My momma always said life was like a box ochocol
Java处理JSON
dyy_gusi
json
Json在数据传输中很好用,原因是JSON 比 XML 更小、更快,更易解析。
在Java程序中,如何使用处理JSON,现在有很多工具可以处理,比较流行常用的是google的gson和alibaba的fastjson,具体使用如下:
1、读取json然后处理
class ReadJSON
{
public static void main(String[] args)
win7下nginx和php的配置
geeksun
nginx
1. 安装包准备
nginx : 从nginx.org下载nginx-1.8.0.zip
php: 从php.net下载php-5.6.10-Win32-VC11-x64.zip, php是免安装文件。
RunHiddenConsole: 用于隐藏命令行窗口
2. 配置
# java用8080端口做应用服务器,nginx反向代理到这个端口即可
p
基于2.8版本redis配置文件中文解释
hongtoushizi
redis
转载自: http://wangwei007.blog.51cto.com/68019/1548167
在Redis中直接启动redis-server服务时, 采用的是默认的配置文件。采用redis-server xxx.conf 这样的方式可以按照指定的配置文件来运行Redis服务。下面是Redis2.8.9的配置文
第五章 常用Lua开发库3-模板渲染
jinnianshilongnian
nginx lua
动态web网页开发是Web开发中一个常见的场景,比如像京东商品详情页,其页面逻辑是非常复杂的,需要使用模板技术来实现。而Lua中也有许多模板引擎,如目前我在使用的lua-resty-template,可以渲染很复杂的页面,借助LuaJIT其性能也是可以接受的。
如果学习过JavaEE中的servlet和JSP的话,应该知道JSP模板最终会被翻译成Servlet来执行;而lua-r
JZSearch大数据搜索引擎
颠覆者
JavaScript
系统简介:
大数据的特点有四个层面:第一,数据体量巨大。从TB级别,跃升到PB级别;第二,数据类型繁多。网络日志、视频、图片、地理位置信息等等。第三,价值密度低。以视频为例,连续不间断监控过程中,可能有用的数据仅仅有一两秒。第四,处理速度快。最后这一点也是和传统的数据挖掘技术有着本质的不同。业界将其归纳为4个“V”——Volume,Variety,Value,Velocity。大数据搜索引
10招让你成为杰出的Java程序员
pda158
java 编程 框架
如果你是一个热衷于技术的
Java 程序员, 那么下面的 10 个要点可以让你在众多 Java 开发人员中脱颖而出。
1. 拥有扎实的基础和深刻理解 OO 原则 对于 Java 程序员,深刻理解 Object Oriented Programming(面向对象编程)这一概念是必须的。没有 OOPS 的坚实基础,就领会不了像 Java 这些面向对象编程语言
tomcat之oracle连接池配置
小网客
oracle
tomcat版本7.0
配置oracle连接池方式:
修改tomcat的server.xml配置文件:
<GlobalNamingResources>
<Resource name="utermdatasource" auth="Container"
type="javax.sql.DataSou
Oracle 分页算法汇总
vipbooks
oracle sql 算法 .net
这是我找到的一些关于Oracle分页的算法,大家那里还有没有其他好的算法没?我们大家一起分享一下!
-- Oracle 分页算法一
select * from (
select page.*,rownum rn from (select * from help) page
-- 20 = (currentPag