1. 程式人生 > >高併發rpc時如何connect(非阻塞)

高併發rpc時如何connect(非阻塞)

方案一:之前有設計中轉伺服器,用於轉發redis、url等訊息。
在這裡面,專門開執行緒負責套接字的連線與重連。使用阻塞等待式的方式直到連線真正連上,效率低下。程式碼如下:

bool Connect(int &sock, sockaddr *addr_ptr, int wait_time)
{
    int connect_res = ::connect(sock, addr_ptr, sizeof(sockaddr));
    if(0 != connect_res && errno != EINPROGRESS)
        return false;


    int
ep_fd = epoll_create(10240); struct epoll_event ev = {0}; ev.data.fd = sock; ev.events = EPOLLOUT; if(epoll_ctl(ep_fd, EPOLL_CTL_ADD, sock, &ev) == -1) { return false; } struct epoll_event events[10]; while(wait_time--) { int ret = epoll_wait(ep_fd, events, 10
, 100); if(0 < ret) { if(events[0].events & (EPOLLERR | EPOLLHUP)) { Destroy(ep_fd); return false; } else if(events[0].events & EPOLLOUT) { connect_res = connect(sock, addr_ptr, sizeof(sockaddr)); if
(0 == connect_res || errno == EISCONN) { Destroy(ep_fd); return true; } else if(errno == EALREADY || errno == EINPROGRESS) { continue; } else { Destroy(ep_fd); return false; } } } else if(0 == ret) { continue; } else { Destroy(ep_fd); return false; } } Destroy(ep_fd); return false; }

方案二:
由於網路的不可預測性,connect可能會出現微秒到幾十秒的連線時長,也可能出現連線拒絕連線不可達等現象。如何儘可能少的佔用資源,且兼顧所有這些情況。程式碼如下:

bool Connect(int &sock, sockaddr *addr_ptr)
{
  int connect_res = ::connect(sock, (sockaddr *)&addr_ptr, sizeof(sockaddr));
  if(0 != connect_res && errno != EINPROGRESS && errno != EISCONN)
  {
    close(sock);
    return false;
  }
  return true;
}

看似很簡單,為什麼可以這樣做?
正常connect後,不管對方的地址是否可達,你的網路地址斷開或正常情況等,返回的都是EINPROGRESS,連線正在處理中。
這時直接返回true認為它成功了,實際上很有可能是不成功的,如何驗證:
當有資料需要傳送時,需要判斷此套接字是否可寫,這時如拔掉網線,套接字將會一直不可寫(本地測試大約十幾秒後套接字變成可寫的)。當可寫時,可通過send返回值判定該套接字是否是有效套接字。如果異常再重新連線。這樣connect的非同步返回和需要傳送時判定可寫狀態以及傳送返回值就可以確定是否真正連線上,佔用的資源很少,效率很高。

測試connect連線主要程式碼如圖:
這裡寫圖片描述
當正常時:
這裡寫圖片描述
當拔掉網線時:
這裡寫圖片描述
當拔掉又重新插上時:有可能會連線成功,也有可能連線不成功
這裡寫圖片描述

相關推薦

併發rpc如何connect阻塞

方案一:之前有設計中轉伺服器,用於轉發redis、url等訊息。 在這裡面,專門開執行緒負責套接字的連線與重連。使用阻塞等待式的方式直到連線真正連上,效率低下。程式碼如下: bool Conne

模擬併發請求服務端python gevent

專案背景:對web後端進行高併發的請求,簡單測試服務框架的效能 解決思路:利用python的多執行緒,但python的多執行緒有點“雞肋”, 個人選擇使用簡潔輕便gevent。 解決方案:採用gevent非同步 + requests 進行高併發請求 import time import

Java同步佇列阻塞佇列與阻塞佇列——java併發容器

在併發程式設計中,有時候需要使用執行緒安全的佇列。如果要實現一個執行緒安全的佇列有兩種方式:一種是使用阻塞演算法,另一種是使用非阻塞演算法。 使用阻塞演算法的佇列可以用一個鎖(入隊和出隊用同一把鎖)或兩個鎖(入隊和出隊用不同的鎖)等方式來實現。 非阻塞的實現方式則可以使用

爬蟲必備—性能相關異步阻塞

tornado 異步io 主機 quest cookie article Coding aps 技術 在編寫爬蟲時,性能的消耗主要在IO請求中,當單進程單線程模式下請求URL時必然會引起等待,從而使得請求整體變慢。 1. 同步執行 1 import requests

Node.js:創建應用+回調函數阻塞/阻塞

我們 異步化 沒有 就會 幾分鐘 能說 image console cti 一、創建應用   如果我們使用PHP來編寫後端的代碼時,需要Apache 或者 Nginx 的HTTP 服務器,並配上 mod_php5 模塊和php-cgi。從這個角度看,整個"接收 HTTP 請

beginthreadex()函式在建立多執行緒傳入回撥函式,好像只能傳入全域性函式或類的靜態成員函式,請問能不能傳入類的成員函式呢靜態

C++類成員函式直接作為執行緒回撥函式2009年06月01日 星期一 17:01我以前寫執行緒時要麼老老實實照著宣告寫,要麼使用C++類的靜態成員函式來作為回撥函式,經常會因為執行緒程式碼而破壞封裝.之前雖然知道類成員函式的展開形式,但從沒想過利用過它,昨天看深入ATL時無意中學

java併發之hook例項防止重複啟動程式

package com.test.testThread; import java.io.File; import java.io.IOException; import java.nio.file.Path; import java.nio.file.Paths; import java.util

執行異常和執行異常一般異常的區別

一,異常的概念 Java異常類層次結構圖: Throwable: 有兩個重要的子類:Exception(異常)和 Error(錯誤),二者都是 Java 異常處理的重要子類,各自都包含大量子類。 Error(錯誤):是程式無法處理的錯誤,表示執行應用程式中較嚴重問題。大多數錯誤與程式碼編

併發下的HashMap執行緒不安全

高併發下的HashMap 這些討論是在1.8之前的java下作的分析,1.8的HashMap做了很大的變化,可以保證高併發下的安全性(多執行緒)。 HashMap的容量是有限的。當經過多次元素插入,使得HashMap達到一定飽和度時,Key對映位置發生衝突的

Java NIO學習總結一阻塞特性

NIO(New IO)是從Java 1.4版開始引入的新的IO API,其與標準JAVA IO API的差異本質上體現在資源的利用方式上,這一點可以從現實中餐廳排隊的例子來理解。午飯時間到了,小明準備從三家備選餐廳A、B、C中選擇一家就餐,糟糕的是三家餐廳的位置都滿了,小明

基於 Python 自建分散式併發 RPC 服務

RPC(Remote Procedure Call)服務,即遠端過程呼叫,在網際網路企業技術架構

Linux下UDP的連線程式示例阻塞阻塞

由於前面已有介紹,關於函式就不介紹了 /*server.c_非阻塞式*/ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h>

MQ併發的調優引數設定說明

高可用(主從)與負載均衡架構圖 訊息傳送中的接收Topic訂閱結果訊息佇列URL地址、訊息接收佇列URL地址、訊息代理的傳送與接收佇列URL地址以及訊息轉發器傳送的Topic結果訊息佇列URL地址,均需設定為Failover 地址。 由於訊息佇列元件ActiveMQ是

多執行緒與併發程式設計進階

前言: 使用多執行緒的目的: 充分利用CPU資源,提高程式執行速度 使用多執行緒面臨的挑戰: 上下文切換、死鎖、計算機軟硬體資源的限制等問題 結論: 不是一味地開啟執行緒就能夠讓程式最大限度地併發執行,以及提升執行速度,想利用多執行緒提升程式執行速度需要結合實際

mysql 針對併發下,同時修改單條資料發生衝突導致資料錯誤的問題例如:併發下單,導致庫存為負數

畢業後第一次做的專案就是電商,但是當時也不明白這個問題。 所以給自己埋下一個坑。 先說說當初的做法,和遇到的問題。 //開啟事務 start transaction; //查詢庫存 select number from item where id = 1; //如果大於購買

併發程式設計與併發解決方案學習Java 記憶體模型

JMM(Java Memory Model)    JMM是一種規範,規範了Java虛擬機器與計算機記憶體是如何協同工作的,規定了一個執行緒如何和何時可以看到其他執行緒修改過的共享變數的值,以及在必須的時候如果同步的訪問共享變數。棧    棧的優勢:存取速度比堆要快,僅次於計

2017.4.26 慕課網--Java 併發秒殺API

Java高併發秒殺API系列(一)                  -----------------業務分析及Dao層 第一章 課程介紹 1.1 內容介紹及業務分析 (1)課程內容 1 SSM框架的整合使用 2 秒殺類系統需求理解和實現 3 常用技術解決高併發問題 (

併發程式慎用strncpy和sprintf

           分享一下最近做程式優化的一點小心得:在寫高併發交易程式碼時要謹慎使用strncpy和sprintf。        &nbs

併發訪問如何確保伺服器端session過多而造成記憶體溢位致使伺服器宕機的方法之一

使用者登入後所在登入頁面中設定一個隱藏的iframe標籤。該子頁面會每隔10s中向報告一次線上訊息。程式碼如下: …… <divclass="response"> <iframesrc="response.html"></iframe>

Python基礎-系統程式設計之程序--multiprocessing阻塞阻塞

程序擁有自己獨立的堆和棧,既不共享堆,亦不共享棧,程序由作業系統排程。 執行緒擁有自己獨立的棧和共享的堆,共享堆,不共享棧,執行緒亦由作業系統排程(標準執行緒是的)。 協程和執行緒一樣共享堆,不共享棧,協程由程式設計師在協程的程式碼裡顯示排程 multiproces