<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      一些網絡編程方面的總結,以及redis、memcache、nginx組件的一些介紹

      網絡編程主要關注的一些問題

      主要關注3個方面的問題

      1. 連接的建立
      2. 連接的斷開
      3. 消息的發送和到達

      連接的建立

      主要分為兩種情況:服務器處理接受客戶端的連接;服務端作為客戶端的連接第三方服務;

      //這是服務端接受客戶端連接的時候;(三次握手完畢)
      int clientfd=accept(listenfd,addr,sz);
      //服務端作為客戶端連接第三方服務
      //這里又分為阻塞IO和非阻塞IO
      int connectfd=soket(AF_INET,SOCK_STREAM,0);
      int ret=connect(connectfd,(struct sockaddr*)&addr,sizeof(addr))
      //阻塞情況:
      //直接return 0;
      //非阻塞情況:
      //ret==-1 && errno=EINPROGRESS正在建立連接
      //ret==-1 && errno=EISCONN 連接建立成功
      

      連接的斷開

      分為兩種:一種主動斷開和被動斷開

      //主動關閉
      close(fd);
      //主動關閉本地讀寫端
      shutdown(fd,SHUT_RDWR);
      //主動關閉本地讀端,對端寫端關閉
      shutdown(fd,SHUT_RD);
      //主動關閉本地寫端,對端讀端關閉
      shutdown(fd,SHUT_WR);
      
      // 被動:讀端關閉
      int n =read(fd,buf,sz);
      if(n==0){
        close_read(fd);
      }
      
      //被動:寫端關閉
      int n = write(fd,buf,sz);
      if(n==-1&&errno==EPIPE){
        close_write(fd);
      }
      

      消息的到達

      從緩沖區中讀取數據:

      int n= read(fd,buf,sz);
      if(n<0){
        if(errno==EINTR || errno == EWOULDBLOCK)
        {
          break;
        }
        close(fd);
      }else if(n ==0 ){
        close(fd);
      }else{
        //處理buf
      }
      

      消息的發送完畢

      往寫緩沖區中寫數據:

      int n =write(fd,buf,dz);
      if (n == -1) {
      if (errno == EINTR || errno == EWOULDBLOCK) {
      return;
      }
      close(fd);
      }
      

      網絡IO的職責

      檢測IO

      io 函數本身可以檢測 io 的狀態;但是只能檢測一個 fd 對應的狀態;io 多路復用可以同時檢測多個io的狀態;區別是:io函數可以檢測具體狀態;io 多路復用只能檢測出可讀、可寫、錯誤、斷開等籠統的事件

      操作IO

      只能使用 io 函數來進行操作;分為兩種操作方式:阻塞 io 和非阻塞 io;

      阻塞 IO 和 非阻塞 IO

      阻塞在網絡線程;
      連接的 fd 阻塞屬性決定了 io 函數是否阻塞;
      具體差異在:io 函數在數據未到達時是否立刻返回;

      // 默認情況下,fd 是阻塞的,設置非阻塞的方法如下;
      int flag = fcntl(fd, F_GETFL, 0);
      fcntl(fd, F_SETFL, flag | O_NONBLOCK);
      

      IO多路復用

      io 多路復用只負責檢測io,不負責操作io;
      int n = epoll_wait(epfd, evs, sz, timeout);
      timeout = -1 一直阻塞直到網絡事件到達;
      imeout = 0 不管是否有事件就緒立刻返回;
      timeout = 1000 最多等待 1 s,如果1 s內沒有事件觸發則返回

      EPoll

      結構以及接口

      struct eventpoll {
      // ...
      struct rb_root rbr; // 管理 epoll 監聽的事件
      struct list_head rdllist; // 保存著 epoll_wait 返回滿?條件的事件
      // ...
      };
      struct epitem {
      // ...
      struct rb_node rbn; // 紅?樹節點
      struct list_head rdllist; // 雙向鏈表節點
      struct epoll_filefd ffd; // 事件句柄信息
      struct eventpoll *ep; // 指向所屬的eventpoll對象
      struct epoll_event event; // 注冊的事件類型
      // ...
      };
      struct epoll_event {
      __uint32_t events; // epollin epollout epollel(邊緣觸發)
      epoll_data_t data; // 保存 關聯數據
      };
      typedef union epoll_data {
      void *ptr;
      int fd;
      uint32_t u32;
      uint64_t u64;
      }epoll_data_t;
      int epoll_create(int size);
      /**
      op:
      EPOLL_CTL_ADD
      EPOLL_CTL_MOD
      EPOLL_CTL_DEL
      event.events:
      EPOLLIN 注冊讀事件
      EPOLLOUT 注冊寫事件
      EPOLLET 注冊邊緣觸發模式,默認是水平觸發
      */
      int epoll_ctl(int epfd, int op, int fd, struct epoll_event* event);
      /**
      events[i].events:
      EPOLLIN 觸發讀事件
      EPOLLOUT 觸發寫事件
      EPOLLERR 連接發生錯誤
      EPOLLRDHUP 連接讀端關閉
      EPOLLHUP 連接雙端關閉
      */
      int epoll_wait(int epfd, struct epoll_event* events, int maxevents, int
      timeout);
      
      

      調用 epoll_create 會創建一個 epoll 對象;調用 epoll_ctl 添加到 epoll 中的事件都會與網卡驅動程序建立回調關系,相應事件觸發時會調用回調函數(ep_poll_callback ),將觸發的事件拷貝到 rdlist 雙向鏈表中;調用 epoll_wait 將會把 rdlist 中就緒事件拷貝到用戶態中;

      epoll 編程

      連接建立

      // 一、處理客戶端的連接
      // 1. 注冊監聽 listenfd 的讀事件
      struct epoll_event ev;
      ev.events |= EPOLLIN;
      epoll_ctl(efd, EPOLL_CTL_ADD, listenfd, &ev);
      // 2. 當觸發 listenfd 的讀事件,調用 accept 接收新的連接
      int clientfd = accept(listenfd, addr, sz);
      struct epoll_event ev;
      ev.events |= EPOLLIN;
      epoll_ctl(efd, EPOLL_CTL_ADD, clientfd, &ev);
      // 二、處理連接第三方服務
      // 1. 創建 socket 建立連接
      int connectfd = socket(AF_INET, SOCK_STREAM, 0);
      connect(connectfd, (struct sockaddr *)&addr, sizeof(addr));
      // 2. 注冊監聽 connectfd 的寫事件
      struct epoll_event ev;
      ev.events |= EPOLLOUT;
      epoll_ctl(efd, EPOLL_CTL_ADD, connectfd, &ev);
      // 3. 當 connectfd 寫事件被觸發,連接建立成功
      if (status == e_connecting && e->events & EPOLLOUT) {
      status == e_connected;
      // 這里需要把寫事件關閉
      epoll_ctl(epfd, EPOLL_CTL_DEL, connectfd, NULL);
      }
      

      連接斷開

      if (e->events & EPOLLRDHUP) {
      // 讀端關閉
      close_read(fd);
      close(fd);
      }
      if (e->events & EPOLLHUP) {
      // 讀寫端都關閉
      close(fd);
      }
      
      

      數據到達

      // reactor 要用非阻塞io
      // select
      if (e->events & EPOLLIN) {
      while (1) {
      int n = read(fd, buf, sz);
      if (n < 0) {
      if (errno == EINTR)
      continue;
      if (errno == EWOULDBLOCK)
      break;
      close(fd);
      } else if (n == 0) {
      close_read(fd);
      // close(fd);
      }
      // 業務邏輯了
      }
      }
      

      reactor應用

      下面就要開始介紹一下redis,memcached,nginx網絡組件了。
      這是我們自己的理解。

      The reactor design pattern is an event handling pattern (事件處理模式)for handling service requests delivered concurrently to a service handler by one or more inputs(處理一個或多個并發傳遞到服務端的服務請求). The service handler then demultiplexes the incoming requests and dispatches them synchronously (同步)to the associated request handlers.

      Redis :

      Redis支持數據的持久化,可以將內存中的數據保存在磁盤中,重啟的時候可以再次加載進行使用。
      Redis不僅僅支持簡單的key-value類型的數據,同時還提供list,set,zset,hash等數據結構的存儲。
      Redis支持數據的備份,即master-slave模式的數據備份。

      redis主要使用的是單reactor的模式

      • 單線程業務邏輯
      • 命令處理是單線程的

      具體的模型如下:

      memcached:
      Memcached,簡單來說就是一個免費開源并且高性能的分布式內存對象緩存系統,主要用于加速動態 Web 程序,減輕數據庫負載。
      他也是key和value的內存數據庫
      命令處理是多線程的。

      memcached為什么使用多reactor?

      • KV數據操作簡單
      • 更高程度并發處理業務
        具體的模型如下:

      nginx:
      nginx采用多進程模型,含一個master進程和多個worker進程,worker進程數目可配置,一般與機器CPU核心數目一致,master進程主要職責是:接收外界信號,如star,stop,restart,監控worker進程狀態。worker進程主要職責:負責處理客戶端請求。
      使用反向代理,多進程處理業務的模式

      nginx為什么要使用多進程?

      • 業務類型復雜
      • 通過進程隔離避免加鎖
        但是多進程模式,很容易就會在接受到請求的時候,由于多進程的響應,導致驚群問題。
        因此通過鎖在用戶態解決驚群問題,目的是為了在用戶層處理連接的負載均衡。
        進程到達7/8 *connections 的時候,不在處理連接,讓其他進程處理連接。
        當所有進程到達7/8 * connections的時候,連接處理將變得緩慢。

      推薦一個零聲學院免費教程,個人覺得老師講得不錯,
      分享給大家:[Linux,Nginx,ZeroMQ,MySQL,Redis,
      fastdfs,MongoDB,ZK,流媒體,CDN,P2P,K8S,Docker,
      TCP/IP,協程,DPDK等技術內容,點擊立即學習:
      服務器
      音視頻
      dpdk
      Linux內核

      posted @ 2022-11-14 11:53  飄雨的河  閱讀(80)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 人与禽交av在线播放| 色噜噜一区二区三区| 久久av高潮av喷水av无码| 国产线播放免费人成视频播放| 老妇肥熟凸凹丰满刺激| 中文字幕乱码熟妇五十中出| 亚洲精品一区二区三区综合| 国产无遮挡猛进猛出免费软件| 亚洲高清WWW色好看美女| 亚洲 小说区 图片区 都市| 国内精品免费久久久久电影院97| 亚洲精品国模一区二区| 国产稚嫩高中生呻吟激情在线视频| 人妻中文字幕亚洲一区| 55夜色66夜色国产精品视频| 欧美性猛交xxxx乱大交极品| 国产成人免费永久在线平台| 亚洲AV无码东方伊甸园| AV最新高清无码专区| 熟女视频一区二区三区嫩草| 亚洲色最新高清AV网站| 中国少妇人妻xxxxx| 中文字幕久久六月色综合| 性人久久久久| 亚洲乱码精品久久久久..| 亚洲不卡一区三区三区四| 久久se精品一区精品二区国产| 人人爽人人爽人人片av东京热| 蜜臀av一区二区三区精品| 中文无码高潮到痉挛在线视频| 年轻女教师hd中字3| 国产精品偷乱一区二区三区| 疯狂做受xxxx高潮欧美日本| 亚洲伊人久久综合成人| 中文丰满岳乱妇在线观看| 国产欧美精品一区二区三区| 亚洲综合av男人的天堂| 99久久99这里只有免费费精品| 最新高清无码专区| 国产成人夜色高潮福利app| 日韩有码av中文字幕|