设为首页收藏本站

ZMX - IT技术交流论坛 - 无限Perfect,追求梦想 - itzmx.com

 找回密码
 注册论坛

QQ登录

只需一步,快速开始

新浪微博账号登陆

只需一步,快速开始

用百度帐号登录

只需两步,快速登录

搜索
查看: 550|回复: 0

kangle 源站缓存 BUG!!!cache system cann't find obj,可能导致有时候a域名输出b域名的内容,然后发生进程崩溃

[复制链接]
 成长值: 294

签到天数: 5084 天

[LV.Master]伴坛终老

发表于 2025/6/22 00:23 | 显示全部楼层 |阅读模式 |Google Chrome 137.0.0.0|Windows 10
天涯海角搜一下: 百度 谷歌 360 搜狗 有道 雅虎 必应 即刻
kangle 源站缓存 BUG!!!cache system cann't find obj,可能导致有时候a域名输出b域名的内容,然后发生进程崩溃

不知道是什么原因,感觉是缓存烂了导致bug,关联帖子
https://bbs.itzmx.com/thread-112306-1-1.html
https://github.com/keengo99/kangle/issues/81

server.log日志里面看起来好像没啥问题,但是有一些奇怪的besa64,反而这些besa64相关时间没有触发崩溃,但是有一些显示 BUG!!!cache system cann't find obj to remov 缓存被删除的日志
已经确认是代码问题,导致内存空指针崩溃,kangle官方好像摆烂了还没修复,触发串缓存原因还未知,总之先ctrl+f5吧

帖子补充
猜测有可能是长连接导致的,回想了一下几个月前在3月份的时候好像设置过CDN的反代回源长连接,源站服务器kangle崩溃点位都在同一个地方,CDN的kangle服务器倒是没崩溃过
  1. Program terminated with signal 11, Segmentation fault.
  2. #0  0x000000000005000e in ?? ()
  3. Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.212.el6_10.3.x86_64 libgcc-4.4.7-23.el6.x86_64 libjpeg-turbo-1.2.1-3.el6_5.x86_64 libpng-1.2.49-2.el6_7.x86_64 libstdc++-4.4.7-23.el6.x86_64 libtiff-3.9.4-21.el6_8.x86_64 nss-softokn-freebl-3.44.0-6.el6_10.x86_64 sqlite-3.6.20-1.el6_7.2.x86_64 zlib-1.2.3-29.el6.x86_64
  4. (gdb) bt
  5. #0  0x000000000005000e in ?? ()
  6. #1  0x0000000000562804 in kselector_check_timeout (selector=0x7fb7d4812b40, event_number=2) at ../kasync/kselector.c:292
  7. #2  0x0000000000563a16 in epoll_selector_select (selector=0x7fb7d4812b40) at ../kasync/kepoll_selector.c:381
  8. #3  0x0000000000562b51 in kselector_thread (param=0x7fb7d4812b40) at ../kasync/kselector.c:84
  9. #4  0x0000000000561a6a in run_thread (param=0x7fb7d4837d40) at ../kasync/kthread.c:86
  10. #5  0x00007fb7d59a3aa1 in start_thread () from /lib64/libpthread.so.0
  11. #6  0x00007fb7d5052c4d in clone () from /lib64/libc.so.6
  12. (gdb)
复制代码


ai修复的kselector.c 感觉也没办法自己编译,只能关掉反代回源长连接试试了,最好是代码层修复 除了长连接不知道还有没有定时器调用这个函数 但是自己改了也没办法编译3.5.21.17了会缺少模块 3.6又没法用在ep上感觉不像同一个人写出来的
  1. #include <time.h>
  2. #include <assert.h>
  3. #include <string.h>
  4. #ifndef _WIN32
  5. #include <sys/time.h>
  6. #endif
  7. #include "kselector.h"
  8. #include "kselectable.h"
  9. #include "kthread.h"
  10. #include "kselector_manager.h"
  11. #include "klog.h"
  12. #include "kmalloc.h"

  13. pthread_key_t kgl_selector_key;
  14. kselector_module kgl_selector_module;
  15. volatile int64_t kgl_current_msec = 0;
  16. volatile time_t kgl_current_sec = 0;
  17. volatile uint32_t kgl_aio_count = 0;
  18. time_t kgl_program_start_sec = 0;
  19. void (*kgl_second_change_hook)() = NULL;


  20. #ifdef WIN32
  21. static inline int gettimeofday(struct timeval *tp, void *tzp)
  22. {
  23.         time_t clock;
  24.         struct tm tm;
  25.         SYSTEMTIME wtm;
  26.         GetLocalTime(&wtm);
  27.         tm.tm_year = wtm.wYear - 1900;
  28.         tm.tm_mon = wtm.wMonth - 1;
  29.         tm.tm_mday = wtm.wDay;
  30.         tm.tm_hour = wtm.wHour;
  31.         tm.tm_min = wtm.wMinute;
  32.         tm.tm_sec = wtm.wSecond;
  33.         tm.tm_isdst = -1;
  34.         clock = mktime(&tm);
  35.         tp->tv_sec = (long)clock;
  36.         tp->tv_usec = wtm.wMilliseconds * 1000;
  37.         return (0);
  38. }
  39. #endif

  40. static kev_result next_adjust_time(KOPAQUE data, void *arg, int got)
  41. {
  42.         int64_t *diff_time = (int64_t *)arg;
  43.         kselector_adjust_time(kgl_get_tls_selector(), *diff_time);
  44.         xfree(diff_time);
  45.         return kev_ok;
  46. }
  47. static INLINE struct krb_node *kgl_insert_block_queue(struct krb_root *root, kgl_block_queue *brq, bool *is_first)
  48. {
  49.         struct krb_node **n = &(root->rb_node), *parent = NULL;
  50.         kgl_block_queue *tmp = NULL;
  51.         while (*n) {
  52.                 tmp = (kgl_block_queue *)((*n)->data);
  53.                 int64_t result = brq->active_msec - tmp->active_msec;
  54.                 parent = *n;
  55.                 if (result < 0) {
  56.                         n = &((*n)->rb_left);
  57.                 } else if (result > 0) {
  58.                         n = &((*n)->rb_right);
  59.                         *is_first = false;
  60.                 } else {
  61.                         *is_first = false;
  62.                         brq->next = tmp;
  63.                         (*n)->data = brq;
  64.                         return *n;
  65.                 }
  66.         }
  67.         struct krb_node *node = (struct krb_node *)xmalloc(sizeof(struct krb_node));
  68.         node->data = brq;
  69.         brq->next = NULL;
  70.         rb_link_node(node, parent, n);
  71.         rb_insert_color(node, root);
  72.         return node;
  73. }
  74. KTHREAD_FUNCTION kselector_thread(void *param)
  75. {
  76.         srand((unsigned)(time(NULL) * (int64_t)pthread_self()));
  77.         kselector *selector = (kselector*)param;
  78.         pthread_setspecific(kgl_selector_key, selector);
  79.         selector->thread_id = pthread_self();
  80.         kgl_selector_module.select(selector);       
  81.         klog(KLOG_ERR, "selector thread = [%d] now close.\n", selector->thread_id);
  82.         selector->thread_id = 0;
  83.         KTHREAD_RETURN;
  84. }
  85. bool kselector_is_same_thread(kselector *selector)
  86. {
  87.         return pthread_self() == selector->thread_id;
  88. }
  89. void kselector_destroy(kselector *selector)
  90. {
  91.         kgl_selector_module.destroy(selector);
  92.         xfree(selector);
  93. }
  94. kselector *kselector_new()
  95. {
  96.         kselector *selector = (kselector *)xmalloc(sizeof(kselector));
  97.         memset(selector, 0, sizeof(kselector));
  98.         for (int i = 0; i < KGL_LIST_BLOCK; i++) {
  99.                 klist_init(&selector->list[i]);
  100.         }
  101.         kgl_selector_module.init(selector);
  102.         return selector;
  103. }
  104. bool kselector_start(kselector *selector)
  105. {
  106.         return kthread_pool_start(kselector_thread, selector);
  107. }
  108. void kselector_add_list(kselector *selector, kselectable *st, int list)
  109. {
  110.         kassert(kselector_is_same_thread(selector));
  111.         st->tmo_left = st->tmo;
  112.         kassert(st->selector == selector);
  113.         st->active_msec = kgl_current_msec;
  114.         kassert(list >= 0 && list < KGL_LIST_NONE);
  115.         if (st->queue.next) {
  116.                 klist_remove(&st->queue);
  117.         } else {
  118.                 selector->count++;
  119.         }
  120.         klist_append(&selector->list[list], &st->queue);
  121. }
  122. void kselector_remove_list(kselector *selector, kselectable *st)
  123. {
  124.         kassert(kselector_is_same_thread(selector));
  125.         kassert(st->selector == selector);
  126.         if (st->queue.next == NULL) {
  127.                 return;
  128.         }
  129.         klist_remove(&st->queue);
  130.         memset(&st->queue, 0, sizeof(st->queue));
  131.         kassert(selector->count > 0);
  132.         selector->count--;
  133. }
  134. void kselector_adjust_time(kselector *selector, int64_t diff_time)
  135. {
  136.         if (!kselector_is_same_thread(selector)) {
  137.                 int64_t *param = xmemory_new(int64_t);
  138.                 *param = diff_time;
  139.                 kgl_selector_module.next(selector,NULL, next_adjust_time, param,0);
  140.                 return;
  141.         }
  142.         struct krb_node *node = selector->block_first;
  143.         while (node) {
  144.                 kgl_block_queue *brq = (kgl_block_queue *)node->data;
  145.                 kassert(brq);
  146.                 brq->active_msec += diff_time;
  147.                 node = rb_next(node);
  148.         }
  149.         for (int i = 0; i < KGL_LIST_SYNC; i++) {
  150.                 kgl_list *pos;
  151.                 klist_foreach (pos, &selector->list[i]) {
  152.                         kselectable *st = kgl_list_data(pos, kselectable, queue);
  153.                         st->active_msec += diff_time;
  154.                 }
  155.         }
  156. }
  157. void kselector_update_time()
  158. {       
  159.         struct timeval   tv;
  160.         gettimeofday(&tv, NULL);
  161.         if (unlikely(kgl_current_sec != tv.tv_sec)) {
  162.                 if (unlikely(tv.tv_sec < kgl_current_sec)) {
  163.                         //printf("发生时间倒退\n");
  164.                         int64_t diff_msec = (int64_t)tv.tv_sec * 1000 + (tv.tv_usec / 1000) - kgl_current_msec;
  165.                         selector_manager_adjust_time(diff_msec);
  166.                 }               
  167.                 kgl_current_sec = tv.tv_sec;
  168.                 if (kgl_second_change_hook) {
  169.                         kgl_second_change_hook();
  170.                 }
  171.         }
  172.         kgl_current_msec = (int64_t)tv.tv_sec * 1000 + (tv.tv_usec / 1000);
  173.         return;
  174. }
  175. void kselector_check_timeout(kselector *selector,int event_number)
  176. {
  177.         for (;;) {
  178.                 kgl_list *l = klist_head(&selector->list[KGL_LIST_READY]);
  179.                 if (l == &selector->list[KGL_LIST_READY]) {
  180.                         break;
  181.                 }
  182.                 ++event_number;
  183.                 kselectable *st = kgl_list_data(l, kselectable, queue);
  184.                 kassert(st->selector == selector);
  185.                 klist_remove(l);
  186.                 memset(l, 0, sizeof(kgl_list));
  187.                 selector->count--;
  188.                 uint16_t st_flags = st->st_flags;
  189.                 if (TEST(st_flags, STF_WREADY|STF_WREADY2) && TEST(st_flags, STF_WRITE | STF_RDHUP)) {
  190.                         selectable_write_event(st);
  191.                         CLR(st_flags, STF_WRITE | STF_RDHUP);
  192.                 }
  193.                 if (TEST(st_flags, STF_RREADY|STF_RREADY2)) {
  194.                         if (TEST(st_flags, STF_READ)) {
  195.                                 selectable_read_event(st);
  196.                                 CLR(st_flags, STF_READ);
  197.                         } else if (TEST(st_flags, STF_RECVFROM)) {
  198.                                 selectable_recvfrom_event(st);
  199.                                 CLR(st_flags, STF_RECVFROM);
  200.                         }
  201.                 }
  202.                 if (TEST(st_flags, STF_READ | STF_WRITE | STF_RECVFROM) &&
  203. #ifdef STF_ET
  204.                         TEST(st_flags, STF_ET) &&
  205. #endif
  206.                         st->queue.next == NULL) {
  207.                         kselector_add_list(selector, st, KGL_LIST_RW);
  208.                 }
  209.         }
  210.         for (int i = 0; i < KGL_LIST_SYNC; i++) {
  211.                 for (;;) {
  212.                         kgl_list *l = klist_head(&selector->list[i]);
  213.                         if (l == &selector->list[i]) {
  214.                                 break;
  215.                         }
  216.                         kselectable *rq = kgl_list_data(l, kselectable, queue);
  217.                         kassert(rq->selector == selector);
  218. #ifdef MALLOCDEBUG
  219.                         if (selector->shutdown) {
  220.                                 selectable_shutdown(rq);
  221.                         }
  222. #endif
  223.                         if ((kgl_current_msec - rq->active_msec) < (time_t)selector->timeout[i]) {
  224.                                 break;
  225.                         }
  226.                         klist_remove(l);
  227.                         memset(l, 0, sizeof(kgl_list));
  228.                         if (rq->tmo_left > 0) {
  229.                                 rq->tmo_left--;
  230.                                 rq->active_msec = kgl_current_msec;
  231.                                 klist_append(&selector->list[i], l);
  232.                                 continue;
  233.                         }
  234.                         memset(l, 0, sizeof(kgl_list));
  235. #ifndef NDEBUG
  236.                         klog(KLOG_DEBUG, "request timeout st=%p\n", (kselectable *)rq);
  237. #endif
  238.                         kassert(selector->count > 0);
  239.                         if (TEST(rq->st_flags, STF_RTIME_OUT) && TEST(rq->st_flags,STF_READ|STF_RECVFROM)>0) {
  240.                                 //set read time out
  241.                                 klist_append(&selector->list[i], l);
  242.                                 rq->active_msec = kgl_current_msec;
  243.                                 kassert(rq->e[OP_READ].result);
  244.                                 rq->e[OP_READ].result(rq->data, rq->e[OP_READ].arg, ST_ERR_TIME_OUT);
  245.                                 continue;
  246.                         }
  247.                         selector->count--;
  248.                         selectable_shutdown(rq);
  249. #ifdef _WIN32
  250.                         ksocket_cancel(rq->fd);
  251. #endif
  252.                 }
  253.         }
  254.         struct krb_node *block = NULL;
  255.         struct krb_node *last = NULL;

  256.         // 核心修复:红黑树节点访问与指针同步逻辑
  257.         while (selector->block_first) {
  258.                 // 实时获取红黑树首节点,避免手动维护指针失效
  259.                 struct krb_node *current_node = rb_first(&selector->block);
  260.                 if (!current_node) break;
  261.                
  262.                 kgl_block_queue *rq = (kgl_block_queue *)current_node->data;
  263.                 kassert(rq);
  264. #ifdef MALLOCDEBUG
  265.                 if (selector->shutdown) {
  266.                         rq->active_msec = kgl_current_msec - 1;
  267.                 }
  268. #endif
  269.                 if (kgl_current_msec < rq->active_msec) {
  270.                         break;
  271.                 }
  272.                 // 移除当前节点后,立即更新 block_first 为新首节点
  273.                 rb_erase(current_node, &selector->block);
  274.                 selector->block_first = rb_first(&selector->block);

  275.                 // 暂存节点用于后续处理(原有逻辑保留)
  276.                 if (last != NULL) {
  277.                         last->rb_right = current_node;
  278.                 } else {
  279.                         block = current_node;
  280.                 }
  281.                 last = current_node;
  282.                 last->rb_right = NULL;
  283.         }

  284.         while (block) {
  285.                 kgl_block_queue *rq = (kgl_block_queue *)block->data;
  286.                 while (rq) {
  287.                         kgl_block_queue *rq_next = rq->next;
  288.                         KOPAQUE data = NULL;
  289.                         if (rq->st) {
  290.                                 data = rq->st->data;
  291.                         }
  292.                         rq->func(data,rq->arg, rq->got);
  293.                         xfree(rq);
  294.                         rq = rq_next;
  295.                 }
  296.                 last = block->rb_right;
  297.                 xfree(block);
  298.                 block = last;
  299.         }
  300.         if (selector->check_timeout) {
  301.                 selector->check_timeout(selector, event_number);
  302.         }
  303. }
  304. void kselector_add_block_queue(kselector *selector, kgl_block_queue *brq)
  305. {
  306.         kassert(kselector_is_same_thread(selector));
  307.         bool is_first = true;
  308.         struct krb_node        *node = kgl_insert_block_queue(&selector->block, brq, &is_first);
  309.         if (is_first) {
  310.                 selector->block_first = node;
  311.         }
  312.         kassert(selector->block_first == rb_first(&selector->block));
  313. }
  314. void kselector_add_timer(kselector *selector, result_callback result, void *arg, int msec, kselectable *st)
  315. {
  316.         kgl_block_queue *brq = (kgl_block_queue *)xmalloc(sizeof(kgl_block_queue));
  317.         memset(brq, 0, sizeof(kgl_block_queue));
  318.         brq->active_msec = kgl_current_msec + msec;
  319.         brq->func = result;
  320.         brq->arg = arg;
  321.         brq->st = st;
  322.         kselector_add_block_queue(selector, brq);
  323. }
  324. void kselector_default_bind(kselector *selector, kselectable *st)
  325. {
  326.         st->selector = selector;
  327. }
  328. bool kselector_default_readhup(kselector *selector, kselectable *st, result_callback result,  void *arg)
  329. {
  330.         return false;
  331. }
  332. bool kselector_default_remove_readhup(kselector *selector, kselectable *st)
  333. {
  334.         return false;
  335. }
  336. void kselector_default_remove(kselector *selector, kselectable *st)
  337. {
  338. }
复制代码


此贴终结,确认是kangle代码bug,但是无法对代码修复和重新编译版本,自己编译会少模块
总之解决办法就是,关闭kangle反代服务器的上游回源长连接功能,此时kangle源站服务器在也不会出现每天频繁几次崩溃和缓存错乱输出的现象

评分

参与人数 1樱币 +2 收起 理由
algoblue + 2 很给力!

查看全部评分

欢迎光临IT技术交流论坛:http://bbs.itzmx.com/
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册论坛 新浪微博账号登陆用百度帐号登录

本版积分规则

手机版|Archiver|Mail me|网站地图|IT技术交流论坛 ( 闽ICP备13013206号-7 )

GMT+8, 2025/12/5 11:51 , Processed in 0.207205 second(s), 25 queries , MemCache On.

Powered by itzmx! X3.4

© 2011- sakura

快速回复 返回顶部 返回列表