一般這種情況可能的原因有這幾種:
創(chuàng)新互聯(lián)建站專業(yè)為企業(yè)提供寧河網(wǎng)站建設(shè)、寧河做網(wǎng)站、寧河網(wǎng)站設(shè)計、寧河網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計與制作、寧河企業(yè)網(wǎng)站模板建站服務(wù),十多年寧河做網(wǎng)站經(jīng)驗,不只是建網(wǎng)站,更提供有價值的思路和整體網(wǎng)絡(luò)服務(wù)。
1. 可能連接超過mysql設(shè)置的上限(你的應(yīng)該沒超)
2. 程序問題,建立了連接不關(guān)閉(這個有可能,看看你的session)
3. 在沒有使用連接池的情況下,每次都建立一個新的連接到數(shù)據(jù)庫(即使每次操作完畢都及時準確的close了),但是由于可能建立到數(shù)據(jù)庫連接的頻率很高(比如在for循環(huán)里),那么會迅速建立大量的tcp連接到mysql的指定端口,OS在關(guān)閉tcp連接是有一定的延遲的,也是有一定數(shù)量限制的,所以就會出現(xiàn)無法連接的情況(connection refused)。
-------------------------------------
我個人感覺設(shè)置最大連接數(shù)可能用處不大,因為默認的是100,你說剛10個就出問題~所以我覺得可能還是和系統(tǒng)有關(guān)系,因為你說刷新的不頻繁就不會報錯~
不過你到可以先試試看~萬一能行更好不是~
還有啊,你可以找別的機器試驗下,在別人的電腦上做下測試~
one-connection-per-thread
根據(jù)scheduler_functions的模板,我們也可以列出one-connection-per-thread方式的幾個關(guān)鍵函數(shù)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
static scheduler_functions con_per_functions=
{ max_connection+1, // max_threads
NULL,
NULL,
NULL, // init
Init_new_connection_handler_thread, // init_new_connection_thread
create_thread_to_handle_connection, // add_connection
NULL, // thd_wait_begin
NULL, // thd_wait_end
NULL, // post_kill_notification
one_thread_per_connection_end, // end_thread
NULL // end
};
1.init_new_connection_handler_thread
這個接口比較簡單,主要是調(diào)用pthread_detach,將線程設(shè)置為detach狀態(tài),線程結(jié)束后自動釋放所有資源。
2.create_thread_to_handle_connection
這個接口是處理新連接的接口,對于線程池而言,會從thread_id%group_size對應(yīng)的group中獲取一個線程來處理,而one-connection-per-thread方式則會判斷是否有thread_cache可以使用,如果沒有則新建線程來處理。具體邏輯如下:
(1).判斷緩存的線程數(shù)是否使用完(比較blocked_pthread_count 和wake_pthread大小)
(2).若還有緩存線程,將thd加入waiting_thd_list的隊列,喚醒一個等待COND_thread_cache的線程
(3).若沒有,創(chuàng)建一個新的線程處理,線程的入口函數(shù)是do_handle_one_connection
(4).調(diào)用add_global_thread加入thd數(shù)組。
3.do_handle_one_connection
這個接口被create_thread_to_handle_connection調(diào)用,處理請求的主要實現(xiàn)接口。
(1).循環(huán)調(diào)用do_command,從socket中讀取網(wǎng)絡(luò)包,并且解析執(zhí)行;
(2). 當遠程客戶端發(fā)送關(guān)閉連接COMMAND(比如COM_QUIT,COM_SHUTDOWN)時,退出循環(huán)
(3).調(diào)用close_connection關(guān)閉連接(thd-disconnect());
(4).調(diào)用one_thread_per_connection_end函數(shù),確認是否可以復用線程
(5).根據(jù)返回結(jié)果,確定退出工作線程還是繼續(xù)循環(huán)執(zhí)行命令。
4.one_thread_per_connection_end
判斷是否可以復用線程(thread_cache)的主要函數(shù),邏輯如下:
(1).調(diào)用remove_global_thread,移除線程對應(yīng)的thd實例
(2).調(diào)用block_until_new_connection判斷是否可以重用thread
(3).判斷緩存的線程是否超過閥值,若沒有,則blocked_pthread_count++;
(4).阻塞等待條件變量COND_thread_cache
(5).被喚醒后,表示有新的thd需要重用線程,將thd從waiting_thd_list中移除,使用thd初始化線程的thd-thread_stack
(6).調(diào)用add_global_thread加入thd數(shù)組。
(7).如果可以重用,返回false,否則返回ture
線程池與epoll
在引入線程池之前,server層只有一個監(jiān)聽線程,負責監(jiān)聽mysql端口和本地unixsocket的請求,對于每個新的連接,都會分配一個獨立線程來處理,因此監(jiān)聽線程的任務(wù)比較輕松,mysql通過poll或select方式來實現(xiàn)IO的多路復用。引入線程池后,除了server層的監(jiān)聽線程,每個group都有一個監(jiān)聽線程負責監(jiān)聽group內(nèi)的所有連接socket的連接請求,工作線程不負責監(jiān)聽,只處理請求。對于overscribe為1000的線程池設(shè)置,每個監(jiān)聽線程需要監(jiān)聽1000個socket的請求,監(jiān)聽線程采用epoll方式來實現(xiàn)監(jiān)聽。
Select,poll,epoll都是IO多路復用機制,IO多路復用通過一種機制,可以監(jiān)聽多個fd(描述符),比如socket,一旦某個fd就緒(讀就緒或?qū)懢途w),能夠通知程序進行相應(yīng)的讀寫操作。epoll相對于select和poll有了很大的改進,首先epoll通過epoll_ctl函數(shù)注冊,注冊時,將所有fd拷貝進內(nèi)核,只拷貝一次不需要重復拷貝,而每次調(diào)用poll或select時,都需要將fd集合從用戶空間拷貝到內(nèi)核空間(epoll通過epoll_wait進行等待);其次,epoll為每個描述符指定了一個回調(diào)函數(shù),當設(shè)備就緒時,喚醒等待者,通過回調(diào)函數(shù)將描述符加入到就緒鏈表,無需像select,poll方式采用輪詢方式;最后select默認只支持1024個fd,epoll則沒有限制,具體數(shù)字可以參考cat /proc/sys/fs/file-max的設(shè)置。epoll貫穿在線程池使用的過程中,下面我就epoll的創(chuàng)建,使用和銷毀生命周期來描述epoll在線程中是如何使用的。
線程池初始化,epoll通過epoll_create函數(shù)創(chuàng)建epoll文件描述符,實現(xiàn)函數(shù)是thread_group_init;
端口監(jiān)聽線程監(jiān)聽到請求后,創(chuàng)建socket,并創(chuàng)建THD和connection對象,放在對應(yīng)的group隊列中;
工作線程獲取該connection對象時,若還未登錄,則進行登錄驗證
若socket還未注冊到epoll,則調(diào)用epoll_ctl進行注冊,注冊方式是EPOLL_CTL_ADD,并將connection對象放入epoll_event結(jié)構(gòu)體中
若是老連接的請求,仍然需要調(diào)用epoll_ctl注冊,注冊方式是EPOLL_CTL_MOD
group內(nèi)的監(jiān)聽線程調(diào)用epoll_wait來監(jiān)聽注冊的fd,epoll是一種同步IO方式,所以會進行等待
請求到來時,獲取epoll_event結(jié)構(gòu)體中的connection,放入到group中的隊列
線程池銷毀時,調(diào)用thread_group_close將epoll關(guān)閉。
備注:
1.注冊在epoll的fd,若請求就緒,則將對應(yīng)的event放入到events數(shù)組,并將該fd的事務(wù)類型清空,因此對于老的連接請求,依然需要調(diào)用epoll_ctl(pollfd, EPOLL_CTL_MOD, fd, ev)來注冊。
線程池函數(shù)調(diào)用關(guān)系
(1)創(chuàng)建epoll
tp_init-thread_group_init-tp_set_threadpool_size-io_poll_create-epoll_create
(2)關(guān)閉epoll
tp_end-thread_group_close-thread_group_destroy-close(pollfd)
(3)關(guān)聯(lián)socket描述符
handle_event-start_io-io_poll_associate_fd-io_poll_start_read-epoll_ctl
(4)處理連接請求
handle_event-threadpool_process_request-do_command-dispatch_command-mysql_parse-mysql_execute_command
(5)工作線程空閑時
worker_main-get_event-pthread_cond_timedwait
等待thread_pool_idle_timeout后,退出。
(6)監(jiān)聽epoll
worker_main-get_event-listener-io_poll_wait-epoll_wait
(7)端口監(jiān)聽線程
main-mysqld_main-handle_connections_sockets-poll
one-connection-per-thread函數(shù)調(diào)用關(guān)系
(1) 工作線程等待請求
handle_one_connection-do_handle_one_connection-do_command-
my_net_read-net_read_packet-net_read_packet_header-net_read_raw_loop-
vio_read-vio_socket_io_wait-vio_io_wait-poll
備注:與線程池的工作線程有監(jiān)聽線程幫助其監(jiān)聽請求不同,one-connection-per-thread方式的工作線程在空閑時,會調(diào)用poll阻塞等待網(wǎng)絡(luò)包過來;
而線程池的工作線程只需要專心處理請求即可,所以使用也更充分。
(2)端口監(jiān)聽線程
與線程池的(7)相同
參考文檔
MySQL的查詢使用的是線程池。當有大量請求并發(fā)訪問時,一定伴隨著資源的不斷創(chuàng)建和釋放,導致資源利用率低,降低了服務(wù)質(zhì)量。線程池技術(shù),預先會創(chuàng)建一定數(shù)量的線程,當有請求達到時,線程池分配一個線程提供服務(wù),請求結(jié)束后,該線程又去服務(wù)其他請求。 通過這種方式,避免了線程和內(nèi)存對象的頻繁創(chuàng)建和釋放,降低了服務(wù)端的并發(fā)度,減少了上下文切換和資源的競爭,提高資源利用效率。在MySQL早期的版本中,處理連接的方式是One-Connection-Per-Thread,即對于每一個數(shù)據(jù)庫連接,MySQL-Server都會創(chuàng)建一個獨立的線程服務(wù),請求結(jié)束后,銷毀線程。再來一個連接請求,則再創(chuàng)建一個連接,結(jié)束后再進行銷毀。但是,這種方式在高并發(fā)情況下,會導致線程的頻繁創(chuàng)建和釋放。當然,通過thread-cache,我們可以將線程緩存起來,以供下次使用,避免頻繁創(chuàng)建和釋放的問題,但是無法解決高連接數(shù)的問題。One-Connection-Per-Thread方式隨著連接數(shù)暴增,導致需要創(chuàng)建同樣多的服務(wù)線程,高并發(fā)線程意味著高的內(nèi)存消耗,更多的上下文切換(cpu cache命中率降低)以及更多的資源競爭,導致服務(wù)出現(xiàn)抖動。相對于One-Thread-Per-Connection方式,一個線程對應(yīng)一個連接,Thread-Pool實現(xiàn)方式中,線程處理的最小單位是statement(語句),一個線程可以處理多個連接的請求。這樣,在保證充分利用硬件資源情況下(合理設(shè)置線程池大小),可以避免瞬間連接數(shù)暴增導致的服務(wù)器抖動。
網(wǎng)頁題目:mysql線程池怎么看 查看數(shù)據(jù)庫連接池數(shù)量 線程池數(shù)量
網(wǎng)址分享:http://m.rwnh.cn/article38/doocipp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供定制網(wǎng)站、、域名注冊、全網(wǎng)營銷推廣、微信小程序、移動網(wǎng)站建設(shè)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)