广告
返回顶部
首页 > 资讯 > 数据库 >Redis偶发连接失败怎么办
  • 241
分享到

Redis偶发连接失败怎么办

2024-04-02 19:04:59 241人浏览 八月长安
摘要

这篇文章主要介绍了Redis偶发连接失败怎么办,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。前言本文主要给大家介绍了关于Redis偶发连接失

这篇文章主要介绍了Redis偶发连接失败怎么办,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。

前言

本文主要给大家介绍了关于Redis偶发连接失败的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧

【作者】

张延俊:携程技术保障中心资深DBA,对数据库架构和疑难问题分析排查有浓厚的兴趣。

寿向晨:携程技术保障中心高级DBA,主要负责携程Redis及DB的运维工作,在自动化运维,流程化及监控排障等方面有较多的实践经验,喜欢深入分析问题,提高团队运维效率。

【问题描述】

 生产环境有一个Redis会偶尔发生连接失败的报错,报错的时间点、客户端IP并没有特别明显的规律,过一会儿,报错会自动恢复。

 以下是客户端报错信息:

CRedis.Client.RExceptions.ExcuteCommandException: Unable to Connect redis server: ---> CRedis.Third.Redis.RedisException: Unable to Connect redis server:
 在 CRedis.Third.Redis.RedisNativeClient.CreateConnectionError()
 在 CRedis.Third.Redis.RedisNativeClient.SendExpectData(Byte[][] cmdWithBinaryArgs)
 在 CRedis.Client.Entities.RedisServer.<>c__DisplayClassd`1.

 从报错的信息来看,应该是连接不上Redis所致。Redis的版本是2.8.19。虽然版本有点老,但基本运行稳定。

 线上环境只有这个集群有偶尔报错。这个集群的一个比较明显的特征是客户端服务器比较多,有上百台。

【问题分析】

 从报错的信息来看,客户端连接不到服务端。常见的原因有以下几点:

  • 一个常见的原因是由于端口耗尽,对网络连接进行排查,在出问题的点上,tcp连接数远没有达到端口耗尽的场景,因此这个不是Redis连接不上的根本原因。

  • 另外一种常见的场景是在服务端有慢查询,导致Redis服务阻塞。我们在Redis服务端,把运行超过10毫秒的语句进行抓取,也没有抓到运行慢的语句。

 从服务端的部署的监控来看,出问题的点上,连接数有一个突然飙升,从3500个连接突然飙升至4100个连接。如下图显示:

Redis偶发连接失败怎么办

同时间,服务器端显示Redis服务端有丢包现象:345539 – 344683 = 856个包。

Sat Apr 7 10:41:40 CST 2018
 1699 outGoing packets dropped
 92 dropped because of missing route
 344683 SYNs to LISTEN Sockets dropped
 344683 times the listen queue of a socket overflowed
Sat Apr 7 10:41:41 CST 2018
 1699 outgoing packets dropped
 92 dropped because of missing route
 345539 SYNs to LISTEN sockets dropped
 345539 times the listen queue of a socket overflowed

 客户端报错的原因基本确定,是因为建连速度太快,导致服务端backlog队列溢出,连接被server端reset。

【关于backlog overflow】

 在高并发的短连接服务中,这是一种很常见的tcp报错类型。一个正常的tcp建连过程如下:

 1.client发送一个(SYN)给server

 2.server返回一个(SYN,ACK)给client

 3.client返回一个(ACK)

 三次握手结束,对client来说建连成功,client可以继续发送数据包给server,但是这个时候server端未必ready,如下图所示 :

Redis偶发连接失败怎么办

在BSD版本内核实现的tcp协议中,server端建连过程需要两个队列,一个是SYN queue,一个是accept queue。前者叫半开连接(或者半连接)队列,在接收到client发送的SYN时加入队列。(一种常见的网络攻击方式就是不断发送SYN但是不发送ACK从而导致server端的半开队列撑爆,server端拒绝服务。)后者叫全连接队列,server返回(SYN,ACK),在接收到client发送ACK后(此时client会认为建连已经完成,会开始发送PSH包),如果accept queue没有满,那么server从SYN queue把连接信息移到accept queue;如果此时accept queue溢出的话,server的行为要看配置。如果tcp_abort_on_overflow为0(默认),那么直接drop掉client发送的PSH包,此时client会进入重发过程,一段时间后server端重新发送SYN,ACK,重新从建连的第二步开始;如果tcp_abort_on_overflow为1,那么server端发现accept queue满之后直接发送reset。

通过wireshark搜索发现在一秒内有超过2000次对Redis Server端发起建连请求。我们尝试修改tcp backlog大小,从511调整到2048, 问题并没有得到解决。所以此类微调,并不能彻底的解决问题。

【网络包分析】

我们用wireshark来识别网络拥塞的准确时间点和原因。我们已经有了准确的报错时间点,先用editcap把超大的tcp包裁剪一下,裁成30秒间隔,并通过wireshark I/O 100ms间隔分析网络阻塞的准确时间点:

Redis偶发连接失败怎么办

 根据图标可以明显看到tcp的packets来往存在block。

 对该block前后的网络包进行明细分析,网络包来往情况如下:

TimeSourceDestDescription
  12:01:54.6536050    Redis-Server    Clients    TCP:Flags=…AP…
  12:01:54.6538580    Redis-Server    Clients    TCP:Flags=…AP…
  12:01:54.6539770    Redis-Server    Clients    TCP:Flags=…AP…
  12:01:54.6720580    Redis-Server    Clients    TCP:Flags=…A..S..
  12:01:54.6727200    Redis-Server    Clients    TCP:Flags=…A……
  12:01:54.6808480    Redis-Server    Clients    TCP:Flags=…AP…..
  12:01:54.6910840    Redis-Server    Clients    TCP:Flags=…A…S.,
  12:01:54.6911950    Redis-Server    Clients    TCP:Flags=…A……
  …     …      …      …
  12:01:56.1181350    Redis-Server    Clients    TCP:Flags=…AP….

12:01:54.6808480, Redis Server端向客户端发送了一个Push包,也就是对于查询请求的一个结果返回。后面的包都是在做连接处理,包括Ack包,Ack确认包,以及重置的RST包,紧接着下面一个Push包是在12:01:56.1181350发出的。中间的间隔是1.4372870秒。也就是说,在这1.4372870秒期间,Redis的服务器端,除了做一个查询,其他的操作都是在做建连,或拒绝连接。

客户端报错的前后逻辑已经清楚了,redis-server卡了1.43秒,client的connection pool被打满,疯狂新建连接,server的accept queue满,直接拒绝服务,client报错。开始怀疑client发送了特殊命令,这时需要确认一下client的最后几个命令是什么,找到redis-server卡死前的第一个包,装一个wireshark的redis插件,看到最后几个命令是简单的get,并且key-value都很小,不至于需要耗费1.43秒才能完成。服务端也没有slow log,此时排障再次陷入僵局。

【进一步分析】

为了了解这1.43秒之内,Redis Server在做什么事情,我们用pstack来抓取信息。Pstack本质上是gdb attach. 高频率的抓取会影响redis的吞吐。死循环0.5秒一次无脑抓,在redis-server卡死的时候抓到堆栈如下(过滤了没用的栈信息):

Thu May 31 11:29:18 CST 2018
Thread 1 (Thread 0x7ff2db6de720 (LWP 8378)):
#0 0x000000000048cec4 in ?? ()
#1 0x00000000004914a4 in je_arena_ralloc ()
#2 0x00000000004836a1 in je_realloc ()
#3 0x0000000000422cc5 in zrealloc ()
#4 0x00000000004213D7 in sdsRemoveFreeSpace ()
#5 0x000000000041ef3c in clientsCronResizeQueryBuffer ()
#6 0x00000000004205de in clientsCron ()
#7 0x0000000000420784 in serverCron ()
#8 0x0000000000418542 in aeProcessEvents ()
#9 0x000000000041873b in aeMain ()
#10 0x0000000000420fce in main ()
Thu May 31 11:29:19 CST 2018
Thread 1 (Thread 0x7ff2db6de720 (LWP 8378)):
#0 0x0000003729ee5407 in madvise () from /lib64/libc.so.6
#1 0x0000000000493a4e in je_pages_purge ()
#2 0x000000000048cf70 in ?? ()
#3 0x00000000004914a4 in je_arena_ralloc ()
#4 0x00000000004836a1 in je_realloc ()
#5 0x0000000000422cc5 in zrealloc ()
#6 0x00000000004213d7 in sdsRemoveFreeSpace ()
#7 0x000000000041ef3c in clientsCronResizeQueryBuffer ()
#8 0x00000000004205de in clientsCron ()
#9 0x0000000000420784 in serverCron ()
#10 0x0000000000418542 in aeProcessEvents ()
#11 0x000000000041873b in aeMain ()
#12 0x0000000000420fce in main ()
Thu May 31 11:29:19 CST 2018
Thread 1 (Thread 0x7ff2db6de720 (LWP 8378)):
#0 0x000000000048108c in je_malloc_usable_size ()
#1 0x0000000000422be6 in zmalloc ()
#2 0x00000000004220bc in sdsnewlen ()
#3 0x000000000042c409 in createStringObject ()
#4 0x000000000042918e in proceSSMultibulkBuffer ()
#5 0x0000000000429662 in processInputBuffer ()
#6 0x0000000000429762 in readQueryFromClient ()
#7 0x000000000041847c in aeProcessEvents ()
#8 0x000000000041873b in aeMain ()
#9 0x0000000000420fce in main ()
Thu May 31 11:29:20 CST 2018
Thread 1 (Thread 0x7ff2db6de720 (LWP 8378)):
#0 0x000000372a60e7cd in write () from /lib64/libpthread.so.0
#1 0x0000000000428833 in sendReplyToClient ()
#2 0x0000000000418435 in aeProcessEvents ()
#3 0x000000000041873b in aeMain ()
#4 0x0000000000420fce in main ()

重复多次抓取后,从堆栈中发现可疑堆栈clientsCronResizeQueryBuffer位置,属于serverCron()函数下,这个redis-server内部的定时调度,并不在用户线程下,这个解释了为什么卡死的时候没有出现慢查询。

查看redis源码,确认到底redis-server在做什么:

clientsCron(server.h):
#define CLIENTS_CRON_MIN_ITERATIONS 5
void clientsCron(void) {
 
 int numclients = listLength(server.clients);
 int iterations = numclients/server.hz;
 mstime_t now = mstime();

 
 if (iterations < CLIENTS_CRON_MIN_ITERATIONS)
  iterations = (numclients < CLIENTS_CRON_MIN_ITERATIONS) ?
      numclients : CLIENTS_CRON_MIN_ITERATIONS;

 while(listLength(server.clients) && iterations--) {
  client *c;
  listnode *head;

  
  listRotate(server.clients);
  head = listFirst(server.clients);
  c = listNodeValue(head);
  
  if (clientsCronHandleTimeout(c,now)) continue;
  if (clientsCronResizeQueryBuffer(c)) continue;
 }
}

clientsCron首先判断当前client的数量,用于控制一次清理连接的数量,生产服务器单实例的连接数量在5000不到,也就是一次清理的连接数是50个。

clientsCronResizeQueryBuffer(server.h):


int clientsCronResizeQueryBuffer(client *c) {
 size_t querybuf_size = sdsAllocSize(c->querybuf);
 time_t idletime = server.unixtime - c->lastinteraction;

 
 if (((querybuf_size > PROTO_MBULK_BIG_ARG) &&
   (querybuf_size/(c->querybuf_peak+1)) > 2) ||
   (querybuf_size > 1024 && idletime > 2))
 {
  
  if (sdsavail(c->querybuf) > 1024) {
   c->querybuf = sdsRemoveFreeSpace(c->querybuf);
  }
 }
 
 c->querybuf_peak = 0;
 return 0;
}

如果redisClient对象的query buffer满足条件,那么就直接resize掉。满足条件的连接分成两种,一种是真的很大的,比该客户端一段时间内使用的峰值还大;还有一种是很闲(idle>2)的,这两种都要满足一个条件,就是buffer free的部分超过1k。那么redis-server卡住的原因就是正好有那么50个很大的或者空闲的并且free size超过了1k大小连接的同时循环做了resize,由于redis都属于单线程工作的程序,所以block了client。那么解决这个问题办法就很明朗了,让resize 的频率变低或者resize的执行速度变快。

既然问题出在query buffer上,我们先看一下这个东西被修改的位置:

readQueryFromClient(networking.c):
redisClient *createClient(int fd) {
 redisClient *c = zmalloc(sizeof(redisClient));

 
 if (fd != -1) {
  anetNonBlock(NULL,fd);
  anetEnableTcpNoDelay(NULL,fd);
  if (server.tcpkeepalive)
   aneTKEepAlive(NULL,fd,server.tcpkeepalive);
  if (aeCreateFileEvent(server.el,fd,AE_READABLE,
   readQueryFromClient, c) == AE_ERR)
  {
   close(fd);
   zfree(c);
   return NULL;
  }
 }

 selectDb(c,0);
 c->id = server.next_client_id++;
 c->fd = fd;
 c->name = NULL;
 c->bufpos = 0;
 c->querybuf = sdsempty(); 初始化是0

readQueryFromClient(networking.c):
void readQueryFromClient(aeEventLoop *el, int fd, void *privdata, int mask) {
 redisClient *c = (redisClient*) privdata;
 int nread, readlen;
 size_t qblen;
 REDIS_NOTUSED(el);
 REDIS_NOTUSED(mask);

 server.current_client = c;
 readlen = REDIS_IOBUF_LEN;
 
 if (c->reQtype == REDIS_REQ_MULTIBULK && c->multibulklen && c->bulklen != -1
  && c->bulklen >= REDIS_MBULK_BIG_ARG)
 {
  int remaining = (unsigned)(c->bulklen+2)-sdslen(c->querybuf);

  if (remaining < readlen) readlen = remaining;
 }

 qblen = sdslen(c->querybuf);
 if (c->querybuf_peak < qblen) c->querybuf_peak = qblen;
 c->querybuf = sdsMakeRoomFor(c->querybuf, readlen); 在这里会被扩大

由此可见c->querybuf在连接第一次读取命令后的大小就会被分配至少1024*32,所以回过头再去看resize的清理逻辑就明显存在问题,每个被使用到的query buffer的大小至少就是1024*32,但是清理的时候判断条件是>1024,也就是说,所有的idle>2的被使用过的连接都会被resize掉,下次接收到请求的时候再重新分配到1024*32,这个其实是没有必要的,在访问比较频繁的群集,内存会被频繁得回收重分配,所以我们尝试将清理的判断条件改造为如下,就可以避免大部分没有必要的resize操作:

if (((querybuf_size > REDIS_MBULK_BIG_ARG) &&
   (querybuf_size/(c->querybuf_peak+1)) > 2) ||
   (querybuf_size > 1024*32 && idletime > 2))
 {
  
  if (sdsavail(c->querybuf) > 1024*32) {
   c->querybuf = sdsRemoveFreeSpace(c->querybuf);
  }
 }

这个改造的副作用是内存的开销,按照一个实例5k连接计算,5000*1024*32=160M,这点内存消耗对于上百G内存的服务器完全可以接受。

【问题重现】

在使用修改过源码的Redis server后,问题仍然重现了,客户端还是会报同类型的错误,且报错的时候,服务器内存依然会出现抖动。抓取内存堆栈信息如下:

Thu Jun 14 21:56:54 CST 2018
#3  0x0000003729ee893d in clone () from /lib64/libc.so.6
Thread 1 (Thread 0x7f2dc108d720 (LWP 27851)):
#0  0x0000003729ee5400 in madvise () from /lib64/libc.so.6
#1  0x0000000000493a1e in je_pages_purge ()
#2  0x000000000048cf40 in arena_purge ()
#3  0x00000000004a7dad in je_tcache_bin_flush_large ()
#4  0x00000000004a85e9 in je_tcache_event_hard ()
#5  0x000000000042c0b5 in decrRefCount ()
#6  0x000000000042744d in resetClient ()
#7  0x000000000042963b in processInputBuffer ()
#8  0x0000000000429762 in readQueryFromClient ()
#9  0x000000000041847c in aeProcessEvents ()
#10 0x000000000041873b in aeMain ()
#11 0x0000000000420fce in main ()
Thu Jun 14 21:56:54 CST 2018
Thread 1 (Thread 0x7f2dc108d720 (LWP 27851)):
#0  0x0000003729ee5400 in madvise () from /lib64/libc.so.6
#1  0x0000000000493a1e in je_pages_purge ()
#2  0x000000000048cf40 in arena_purge ()
#3  0x00000000004a7dad in je_tcache_bin_flush_large ()
#4  0x00000000004a85e9 in je_tcache_event_hard ()
#5  0x000000000042c0b5 in decrRefCount ()
#6  0x000000000042744d in resetClient ()
#7  0x000000000042963b in processInputBuffer ()
#8  0x0000000000429762 in readQueryFromClient ()
#9  0x000000000041847c in aeProcessEvents ()
#10 0x000000000041873b in aeMain ()
#11 0x0000000000420fce in main ()

显然,Querybuffer被频繁resize的问题已经得到了优化,但是还是会出现客户端报错。这就又陷入了僵局。难道还有其他因素导致query buffer resize变慢?我们再次抓取pstack。但这时,jemalloc引起了我们的注意。此时回想Redis的内存分配机制,Redis为避免libc内存不被释放导致大量内存碎片的问题,默认使用的是jemalloc用作内存分配管理,这次报错的堆栈信息中都是je_pages_purge () redis在调用jemalloc回收脏页。我们看下jemalloc做了些什么:

arena_purge(arena.c)
static void
arena_purge(arena_t *arena, bool all)
{
 arena_chunk_t *chunk;
 size_t npurgatory;
 if (config_debug) {
  size_t ndirty = 0;

  arena_chunk_dirty_iter(&arena->chunks_dirty, NULL,
   chunks_dirty_iter_cb, (void *)&ndirty);
  assert(ndirty == arena->ndirty);
 }
 assert(arena->ndirty > arena->npurgatory || all);
 assert((arena->nactive >> opt_lg_dirty_mult) < (arena->ndirty -
  arena->npurgatory) || all);

 if (config_stats)
  arena->stats.npurge++;
 npurgatory = arena_compute_npurgatory(arena, all);
 arena->npurgatory += npurgatory;

 while (npurgatory > 0) {
  size_t npurgeable, npurged, nunpurged;

  
  chunk = arena_chunk_dirty_first(&arena->chunks_dirty);
  if (chunk == NULL) {
   arena->npurgatory -= npurgatory;
   return;
  }
  npurgeable = chunk->ndirty;
  assert(npurgeable != 0);

  if (npurgeable > npurgatory && chunk->nruns_adjac == 0) {
 
   arena->npurgatory += npurgeable - npurgatory;
   npurgatory = npurgeable;
  }
  arena->npurgatory -= npurgeable;
  npurgatory -= npurgeable;
  npurged = arena_chunk_purge(arena, chunk, all);
  nunpurged = npurgeable - npurged;
  arena->npurgatory += nunpurged;
  npurgatory += nunpurged;
 }
}

Jemalloc每次回收都会判断所有实际应该清理的chunck并对清理做count,这个操作对于高响应要求的系统是很奢侈的,所以我们考虑通过升级jemalloc的版本来优化purge的性能。Redis 4.0版本发布后,性能有很大的改进,并可以通过命令回收内存,我们线上也正准备进行升级,跟随4.0发布的jemalloc版本为4.1,jemalloc的版本使用的在jemalloc的4.0之后版本的arena_purge()做了很多优化,去掉了计数器的调用,简化了很多判断逻辑,增加了arena_stash_dirty()方法合并了之前的计算和判断逻辑,增加了purge_runs_sentinel,用保持脏块在每个arena LRU中的方式替代之前的保持脏块在arena树的dirty-run-containing chunck中的方式,大幅度减少了脏块purge的体积,并且在内存回收过程中不再移动内存块。代码如下:

arena_purge(arena.c)
static void
arena_purge(arena_t *arena, bool all)
{
 chunk_hooks_t chunk_hooks = chunk_hooks_get(arena);
 size_t npurge, npurgeable, npurged;
 arena_runs_dirty_link_t purge_runs_sentinel;
 extent_node_t purge_chunks_sentinel;

 arena->purging = true;

 
 if (false && config_debug) {
  size_t ndirty = arena_dirty_count(arena);
  assert(ndirty == arena->ndirty);
 }
 assert((arena->nactive >> arena->lg_dirty_mult) < arena->ndirty || all);

 if (config_stats)
  arena->stats.npurge++;

 npurge = arena_compute_npurge(arena, all);
 qr_new(&purge_runs_sentinel, rd_link);
 extent_node_dirty_linkage_init(&purge_chunks_sentinel);

 npurgeable = arena_stash_dirty(arena, &chunk_hooks, all, npurge,
  &purge_runs_sentinel, &purge_chunks_sentinel);
 assert(npurgeable >= npurge);
 npurged = arena_purge_stashed(arena, &chunk_hooks, &purge_runs_sentinel,
  &purge_chunks_sentinel);
 assert(npurged == npurgeable);
 arena_unstash_purged(arena, &chunk_hooks, &purge_runs_sentinel,
  &purge_chunks_sentinel);

 arena->purging = false;
}

【解决问题】

实际上我们有多个选项。可以使用Google的tcmalloc来代替jemalloc,可以升级jemalloc的版本等等。我们根据上面的分析,尝试通过升级jemalloc版本,实际操作为升级Redis版本来解决。我们将Redis的版本升级到4.0.9之后观察,线上客户端连接超时这个棘手的问题得到了解决。

【问题总结】

Redis在生产环境中因其支持高并发,响应快,易操作被广泛使用,对于运维人员而言,其响应时间的要求带来了各种各样的问题,Redis的连接超时问题是其中比较典型的一种,从发现问题,客户端连接超时,到通过抓取客户端与服务端的网络包,内存堆栈定位问题,也被其中一些假象所迷惑,最终通过升级jemalloc(Redis)的版本解决问题,这次最值得总结和借鉴的是整个分析的思路。

感谢你能够认真阅读完这篇文章,希望小编分享的“Redis偶发连接失败怎么办”这篇文章对大家有帮助,同时也希望大家多多支持编程网,关注编程网数据库频道,更多相关知识等着你来学习!

您可能感兴趣的文档:

--结束END--

本文标题: Redis偶发连接失败怎么办

本文链接: https://www.lsjlt.com/news/54987.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Redis偶发连接失败怎么办
    这篇文章主要介绍了Redis偶发连接失败怎么办,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。前言本文主要给大家介绍了关于Redis偶发连接失...
    99+
    2022-10-18
  • redis连接失败怎么解决
    出现redis连接失败的情况,可以尝试以下解决方法:1. 检查网络连接:确保你的网络连接正常,可以尝试使用其他网络连接进行测试。2....
    99+
    2023-09-04
    redis
  • android连接mysql失败怎么办
    android连接mysql失败的解决方法首先,在安卓工程的根目录中,查找到AndroidManifest.xml配置文件;AndroidManifest.xml配置文件查找到后,使用记事本打开;文件打开后,在文件中进行以下修改;#将and...
    99+
    2022-10-12
  • node 连接mysql失败怎么办
    本教程操作环境:Windows10系统、node18.4.0版、Dell G3电脑。node 连接mysql失败怎么办?nodejs连接mysql失败的解决方案:首先检查端口号,用户名,密码,数据库,主机有没有错误。如果没有,再看自己的my...
    99+
    2023-05-14
    mysql Node.js
  • php连接mssql失败怎么办
    本文操作环境:windows7系统、PHP5版、DELL G3电脑php连接mssql失败怎么办?关于PHP无法连接MSSQL数据库的解决办法:php 数据库 sql server extension sqlserver 服务器今天接到一个...
    99+
    2021-06-01
    php mssql
  • php7连接mysql失败怎么办
    本文操作环境:Windows7系统、PHP7.1版、DELL G3电脑php7连接mysql失败怎么办?原因:php5使用mysql_connect函数来进行Mysql数据库的连接操作,但是你会发现,这个方法用到php7上不灵了。原因很简单...
    99+
    2015-01-11
    php7
  • excel连接mysql失败怎么办
    excel连接mysql失败的解决方法当excel连接mysql失败时可以在excel中添加以下代码即可连接到MySQL。Public Sub nckxr()Dim cnn As ADODB.ConnectionDim cnnstr As ...
    99+
    2022-10-12
  • node-sass偶尔安装失败怎么办
    这篇文章主要为大家展示了“node-sass偶尔安装失败怎么办”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“node-sass偶尔安装失败怎么办”这篇文章吧。最...
    99+
    2022-10-19
  • mysql添加连接失败怎么办
    mysql添加连接失败的原因:mysql为开启远程访问权限,只允许本地访问,导致添加连接失败解决方法:首先,在命令行中启动MySQL服务;service mysql start  MySQL服务启动后,在命令行中输入mysql的用户名和密码...
    99+
    2022-10-21
  • ubuntu下mysql连接失败怎么办
    ubuntu中连接mysql失败的解决方法原因:Ubuntu在mysql的配置文件中默认绑定了本机ip,需要修改配置文件并赋予权限。在ubuntu命令行中,打开my.cnf配置文件;/etc/mysql/my.cnfmy.cnf配置文件打开...
    99+
    2022-10-22
  • mysql端口连接失败怎么办
    mysql端口连接失败的解决方法首先,通过ping命令ping主机ip,确保主机网络连接正常;在命令行中,执行以下命令对端口进行检测;#对3306端口进行检测netstat -ntpl |grep 3306端口检测好后,在命令行中开启防火墙...
    99+
    2022-10-16
  • navicat连接数据库失败怎么办
    这篇文章将为大家详细讲解有关navicat连接数据库失败怎么办,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。Navicat连接数据库失败,个人总结原因分两类 :一 : N...
    99+
    2022-10-18
  • 升级mysql后连接失败怎么办
    mysql升级后出现连接失败的原因:mysql升级后使用了新的密码验证机制,导致连接mysql失败解决方法:首先,在命令行中使用CD命令切换到mysql安装目录中的bin目录下;CD \mysql\bin切换到并目录后,在命令行中使用roo...
    99+
    2022-10-16
  • mysql连接服务器失败怎么办
    连接mysql服务器失败的解决方法首先,右键点击“开始”,选择进入“计算机管理”;在计算机管理页面中,点击“服务和应用程序”,在下拉中选择“服务”选项;进入服务页面后,在服务列表中查找到“MySQL”服务选项;查找到MySQL服务后,右键点...
    99+
    2022-10-23
  • 云服务器连接失败怎么办
    如果您的云服务器连接失败,请确保您正在使用的是稳定的互联网连接,并尝试在重新启动之前重新建立连接。如果连接依然无法使用,可能有以下一些原因导致连接失败: 网络连接问题:如果您在使用无线网络时遇到连接问题,请检查您的无线网络连接,看看是否...
    99+
    2023-10-27
    服务器
  • 亚马逊开发者服务器连接失败怎么办
    1、检查连接配置:检查你的开发者服务器的连接配置,确保你已经安装了有效的 SSH 密钥,以及其他必要的 Python 命令。这可以确保你正在使用安全的 SSH 连接,并且你的开发者服务器连接设置是正确的。 2、检查日志:确保你的服务器记录...
    99+
    2023-10-27
    亚马逊 开发者 服务器
  • 连接到云服务器失败怎么办
    连接到云服务器失败怎么办,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。连接到云服务器失败怎么办?在云服务器日常使用过程中,难免不会出现连接失败的问题。可能是因为本地通信网络的问...
    99+
    2023-06-06
  • 云服务器连接失败怎么办啊
    检查网络连接 网络连接是云服务器连接失败的主要原因之一。因此,确保您的云服务器网络连接正常非常重要。可以使用诸如Netscapenavigator之类的工具来检测网络连接,并查看是否有错误或问题。 重启服务器 如果云服务器无法连接...
    99+
    2023-10-27
    服务器
  • 关闭mysql端口连接失败怎么办
    关闭mysql端口连接失败的解决方法当无法通过正常的方式关闭mysql端口时,可以通过修改配置文件实现关闭端口,步骤如下:如:关闭MySQL的3306端口首先,进入MySQL安装目录,在安装目录中查找到my.ini配置文件;查找到my.in...
    99+
    2022-10-04
  • 用php连接数据库失败怎么办
    本教程操作环境:Windows10系统、PHP8.1版、Dell G3电脑。用php连接数据库失败怎么办?PHP连接mysql遇到的坑(附解决方法,亲测有效)PHP连接mysql遇到的坑环境: win10 + PHP5.48 + Apa...
    99+
    2022-11-19
    php 数据库
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作