{"id":1674,"date":"2025-11-10T23:54:39","date_gmt":"2025-11-10T20:54:39","guid":{"rendered":"https:\/\/www.dchost.com\/blog\/cloudflare-ile-websocket-ve-grpc-yayini-nasil-hep-canli-kalir-nginx-timeout-keep%e2%80%91alive-ve-kesintisiz-dagitimin-sirlari\/"},"modified":"2025-11-10T23:54:39","modified_gmt":"2025-11-10T20:54:39","slug":"cloudflare-ile-websocket-ve-grpc-yayini-nasil-hep-canli-kalir-nginx-timeout-keep%e2%80%91alive-ve-kesintisiz-dagitimin-sirlari","status":"publish","type":"post","link":"https:\/\/www.dchost.com\/blog\/cloudflare-ile-websocket-ve-grpc-yayini-nasil-hep-canli-kalir-nginx-timeout-keep%e2%80%91alive-ve-kesintisiz-dagitimin-sirlari\/","title":{"rendered":"Cloudflare ile WebSocket ve gRPC Yay\u0131n\u0131 Nas\u0131l Hep Canl\u0131 Kal\u0131r? Nginx Timeout, Keep\u2011Alive ve Kesintisiz Da\u011f\u0131t\u0131m\u0131n S\u0131rlar\u0131"},"content":{"rendered":"<div class=\"dchost-blog-content-wrapper\"><div id=\"toc_container\" class=\"toc_transparent no_bullets\"><p class=\"toc_title\">\u0130&ccedil;indekiler<\/p><ul class=\"toc_list\"><li><a href=\"#Ofiste_Bir_Aksam_Sessizce_Dusen_Baglantilar\"><span class=\"toc_number toc_depth_1\">1<\/span> Ofiste Bir Ak\u015fam: Sessizce D\u00fc\u015fen Ba\u011flant\u0131lar<\/a><\/li><li><a href=\"#Cloudflare_WebSocket_ve_gRPC_Uclusu_Neden_Nazli\"><span class=\"toc_number toc_depth_1\">2<\/span> Cloudflare, WebSocket ve gRPC \u00dc\u00e7l\u00fcs\u00fc Neden Nazl\u0131?<\/a><\/li><li><a href=\"#Nginxte_WebSocket_Upgrade_Timeout_ve_KeepAlive\"><span class=\"toc_number toc_depth_1\">3<\/span> Nginx\u2019te WebSocket: Upgrade, Timeout ve Keep\u2011Alive<\/a><\/li><li><a href=\"#Nginxte_gRPC_HTTP2_Basliklar_ve_Stabil_Akis\"><span class=\"toc_number toc_depth_1\">4<\/span> Nginx\u2019te gRPC: HTTP\/2, Ba\u015fl\u0131klar ve Stabil Ak\u0131\u015f<\/a><\/li><li><a href=\"#Cloudflare_Ayarlari_HTTP2_gRPC_ve_Sessiz_Timeouts\"><span class=\"toc_number toc_depth_1\">5<\/span> Cloudflare Ayarlar\u0131: HTTP\/2, gRPC ve Sessiz Timeouts<\/a><\/li><li><a href=\"#KeepAlive_Mantigi_Iki_Ucta_Ayni_Nefes\"><span class=\"toc_number toc_depth_1\">6<\/span> Keep\u2011Alive Mant\u0131\u011f\u0131: \u0130ki U\u00e7ta Ayn\u0131 Nefes<\/a><\/li><li><a href=\"#Kesintisiz_Dagitim_Reload_Drain_ve_BlueGreen\"><span class=\"toc_number toc_depth_1\">7<\/span> Kesintisiz Da\u011f\u0131t\u0131m: Reload, Drain ve Blue\u2011Green<\/a><\/li><li><a href=\"#Gercek_Bir_Senaryo_Sohbet_Sunucusunu_Geceden_Canliya_Almak\"><span class=\"toc_number toc_depth_1\">8<\/span> Ger\u00e7ek Bir Senaryo: Sohbet Sunucusunu Geceden Canl\u0131ya Almak<\/a><\/li><li><a href=\"#Sorun_Giderme_Loglar_Izler_ve_Ufak_Sinyaller\"><span class=\"toc_number toc_depth_1\">9<\/span> Sorun Giderme: Loglar, \u0130zler ve Ufak Sinyaller<\/a><\/li><li><a href=\"#Guvenlik_ve_Dengeli_Sinirlar\"><span class=\"toc_number toc_depth_1\">10<\/span> G\u00fcvenlik ve Dengeli S\u0131n\u0131rlar<\/a><\/li><li><a href=\"#Cloudflare_Uzerinden_gRPC_ve_WebSockette_Ince_Ayar\"><span class=\"toc_number toc_depth_1\">11<\/span> Cloudflare \u00dczerinden gRPC ve WebSocket\u2019te \u0130nce Ayar<\/a><\/li><li><a href=\"#Nginx_Reloadi_Guvenle_Almak_Icin_Kucuk_Bir_Rutin\"><span class=\"toc_number toc_depth_1\">12<\/span> Nginx Reload\u2019\u0131 G\u00fcvenle Almak \u0130\u00e7in K\u00fc\u00e7\u00fck Bir Rutin<\/a><\/li><li><a href=\"#Ileri_Dusunceler_Izlenebilirlik_ve_Runbooklar\"><span class=\"toc_number toc_depth_1\">13<\/span> \u0130leri D\u00fc\u015f\u00fcnceler: \u0130zlenebilirlik ve Runbook\u2019lar<\/a><\/li><li><a href=\"#Hizli_Testler_Kucuk_Araclar_Buyuk_Guven\"><span class=\"toc_number toc_depth_1\">14<\/span> H\u0131zl\u0131 Testler: K\u00fc\u00e7\u00fck Ara\u00e7lar, B\u00fcy\u00fck G\u00fcven<\/a><\/li><li><a href=\"#Kapanis_Ufak_Dokunuslarla_Buyuk_Huzur\"><span class=\"toc_number toc_depth_1\">15<\/span> Kapan\u0131\u015f: Ufak Dokunu\u015flarla B\u00fcy\u00fck Huzur<\/a><\/li><\/ul><\/div>\n<h2 id=\"section-1\"><span id=\"Ofiste_Bir_Aksam_Sessizce_Dusen_Baglantilar\">Ofiste Bir Ak\u015fam: Sessizce D\u00fc\u015fen Ba\u011flant\u0131lar<\/span><\/h2>\n<p>Hi\u00e7 ba\u015f\u0131n\u0131za geldi mi? Her \u015fey yolunda derken, paneldeki aktif kullan\u0131c\u0131 say\u0131s\u0131 sabit duruyor ama sohbet odas\u0131nda ses yok. Loglarda k\u0131rm\u0131z\u0131 alarm da yok, CPU rahat, bellek rahat. Ama bir \u015feyler eksik. O g\u00fcn ben de tam bunu ya\u015fad\u0131m. WebSocket ba\u011flant\u0131lar\u0131 birer birer d\u00fc\u015f\u00fcyor, gRPC \u00e7a\u011fr\u0131lar\u0131 ara ara kesiliyor. \u00dcstelik trafi\u011fi Cloudflare \u00fczerinden ge\u00e7iriyorum, arkada Nginx var. Birka\u00e7 dakika durup d\u00fc\u015f\u00fcnd\u00fcm: \u201cBu i\u015f ya <strong>timeout<\/strong>, ya da <strong>keep\u2011alive<\/strong> ayarlar\u0131ndan.\u201d<\/p>\n<p>\u0130\u015fin asl\u0131, WebSocket ve gRPC gibi s\u00fcrekli ba\u011flant\u0131 seven servisler, arada bir <strong>CDN\/proxy katman\u0131<\/strong> ve arkada bir <strong>reverse proxy<\/strong> oldu\u011funda daha nazl\u0131 oluyor. Zincirin bir halkas\u0131 k\u0131sa s\u00fcreli\u011fine bile pes etse, kullan\u0131c\u0131 orada kesintiyi hissediyor. Bu yaz\u0131da, Cloudflare ile WebSocket ve gRPC trafi\u011fini <strong>Nginx<\/strong> \u00fczerinden sorunsuz yay\u0131nlamak i\u00e7in neleri ayarlad\u0131\u011f\u0131m\u0131, nerede tak\u0131ld\u0131\u011f\u0131m\u0131 ve sonunda nas\u0131l huzurla deploy alabildi\u011fimi anlataca\u011f\u0131m. Teknik ama g\u00f6z korkutmayan, pratik ama abart\u0131s\u0131z gidiyoruz. \u0130sterseniz beraber ilerleyelim.<\/p>\n<h2 id=\"section-2\"><span id=\"Cloudflare_WebSocket_ve_gRPC_Uclusu_Neden_Nazli\">Cloudflare, WebSocket ve gRPC \u00dc\u00e7l\u00fcs\u00fc Neden Nazl\u0131?<\/span><\/h2>\n<p>Mesela \u015f\u00f6yle d\u00fc\u015f\u00fcn\u00fcn: Taray\u0131c\u0131 bir kere ba\u011flan\u0131yor ve \u201chadi art\u0131k kopmayal\u0131m\u201d diyor. WebSocket\u2019te bu tek soket \u00fczerinden konu\u015fmaya devam ediyorsunuz. gRPC\u2019de ise HTTP\/2\u2019nin ak\u0131\u015fl\u0131 yap\u0131s\u0131ndan yararlan\u0131yorsunuz. Araya Cloudflare gibi bir katman koydu\u011funuzda ba\u011flant\u0131 ikiye \u00e7atallan\u0131yor: \u0130stemci ile Cloudflare ve Cloudflare ile origin (Nginx). \u0130ki ayr\u0131 d\u00fcnya, iki ayr\u0131 ritim. Birinde her \u015fey yolunda olsa bile, di\u011ferinin nabz\u0131 d\u00fc\u015ft\u00fc\u011f\u00fcnde kopma hissi olu\u015fuyor.<\/p>\n<p>Cloudflare bu trafi\u011fi ta\u015f\u0131may\u0131 seviyor; fakat kendi <strong>limitleri<\/strong>, <strong>idle<\/strong> beklentileri ve <strong>planlara ba\u011fl\u0131 davran\u0131\u015flar\u0131<\/strong> var. O y\u00fczden Nginx taraf\u0131ndaki <strong>timeout<\/strong> ve <strong>keep\u2011alive<\/strong> ayarlar\u0131, Cloudflare\u2019\u0131n ritmine uymazsa kopmalar sessizce ba\u015fl\u0131yor. \u0130\u015fin bir g\u00fczel yan\u0131 var: Birka\u00e7 sa\u011flam d\u00fczenleme ile bu nazl\u0131 \u00fc\u00e7l\u00fc \u00e7ok tatl\u0131 \u00e7al\u0131\u015f\u0131yor ve da\u011f\u0131t\u0131m anlar\u0131nda bile m\u00fc\u015fteriden \u201ckopma oldu\u201d mesaj\u0131 alm\u0131yorsunuz.<\/p>\n<h2 id=\"section-3\"><span id=\"Nginxte_WebSocket_Upgrade_Timeout_ve_KeepAlive\">Nginx\u2019te WebSocket: Upgrade, Timeout ve Keep\u2011Alive<\/span><\/h2>\n<p>WebSocket\u2019te kritik nokta, HTTP\u2019den WebSocket\u2019e <strong>Upgrade<\/strong> ba\u015fl\u0131klar\u0131n\u0131 do\u011fru ge\u00e7irmek. Sonra da ba\u011flant\u0131y\u0131 gereksiz yere k\u0131sa kesmemek. Benim kafamda \u015fu s\u0131ralama oturdu: \u00f6nce Upgrade ba\u015fl\u0131klar\u0131, sonra <strong>proxy_http_version 1.1<\/strong>, ard\u0131ndan <strong>proxy_read_timeout<\/strong> ve <strong>proxy_send_timeout<\/strong>. Son olarak upstream\u2019te <strong>keepalive<\/strong> havuzu ve makul <strong>fail<\/strong> ayarlar\u0131. \u0130\u015f, hem ayarlar\u0131n birlikte \u00e7al\u0131\u015fmas\u0131na hem de de\u011ferlerin birbiriyle tutarl\u0131 olmas\u0131na bak\u0131yor.<\/p>\n<p>A\u015fa\u011f\u0131ya pratik bir iskelet b\u0131rak\u0131yorum. Rakamlar\u0131 birebir kopyalamak zorunda de\u011filsiniz; sizin trafik deseninize g\u00f6re yumu\u015fat\u0131n. Ama mant\u0131k bu ak\u0131\u015fta kals\u0131n:<\/p>\n<pre class=\"language-nginx line-numbers\"><code class=\"language-nginx\">map $http_upgrade $connection_upgrade {\n    default upgrade;\n    ''      close;\n}\n\nupstream ws_backend {\n    server 127.0.0.1:8080 max_fails=3 fail_timeout=10s;\n    keepalive 64;\n}\n\nserver {\n    listen 443 ssl http2;\n    server_name ws.example.com;\n\n    # TLS ayarlar\u0131 (sertifikalar vs.)\n\n    # Genel keep-alive\n    keepalive_timeout 65s;\n    keepalive_requests 1000;\n\n    location \/ws\/ {\n        proxy_http_version 1.1;\n        proxy_set_header Upgrade $http_upgrade;\n        proxy_set_header Connection $connection_upgrade;\n\n        proxy_read_timeout 3600s;   # Uzun oturumlar i\u00e7in\n        proxy_send_timeout 3600s;\n        proxy_buffering off;        # WS i\u00e7in tamponlama gereksiz\n\n        proxy_set_header Host $host;\n        proxy_pass http:\/\/ws_backend;\n    }\n}\n<\/code><\/pre>\n<p>Burada \u00f6nemli bir p\u00fcf noktas\u0131 var: Nginx taraf\u0131nda ba\u011flant\u0131y\u0131 nazik\u00e7e uzun tutarken, Cloudflare\u2019\u0131n da kendi taraf\u0131nda WebSocket trafi\u011fini kabul etti\u011finden emin olun. Panelde DNS kayd\u0131n\u0131z\u0131n <strong>turuncu bulut<\/strong> ile proxy\u2019lenmi\u015f olmas\u0131 gerekiyor. Cloudflare taraf\u0131ndaki g\u00fcncel \u00f6zellikleri g\u00f6rmek i\u00e7in <a href=\"https:\/\/developers.cloudflare.com\/websockets\/\" target=\"_blank\" rel=\"noopener nofollow\">Cloudflare\u2019\u0131n WebSocket belgelerine<\/a> bir g\u00f6z atman\u0131z iyi olur.<\/p>\n<h2 id=\"section-4\"><span id=\"Nginxte_gRPC_HTTP2_Basliklar_ve_Stabil_Akis\">Nginx\u2019te gRPC: HTTP\/2, Ba\u015fl\u0131klar ve Stabil Ak\u0131\u015f<\/span><\/h2>\n<p>gRPC, HTTP\/2\u2019nin \u00fczerine kurulu. Bu y\u00fczden Nginx\u2019te <strong>http2<\/strong> ile dinlemek ve <strong>grpc_pass<\/strong> kullanmak gerekiyor. WebSocket\u2019teki gibi \u201cUpgrade\u201d yok, ama uzun ya\u015fayan ak\u0131\u015flar var. gRPC\u2019de <strong>grpc_read_timeout<\/strong>, <strong>grpc_send_timeout<\/strong> ve upstream\u2019te <strong>keepalive<\/strong> \u00e7ok i\u015f g\u00f6r\u00fcyor. Bir de servis de\u011fi\u015fimi s\u0131ras\u0131nda hataya d\u00fc\u015fmemek i\u00e7in <strong>max_fails<\/strong> ve <strong>fail_timeout<\/strong> ayarlar\u0131yla nazik davranmak g\u00fczel sonu\u00e7 veriyor.<\/p>\n<pre class=\"language-nginx line-numbers\"><code class=\"language-nginx\">upstream grpc_backend {\n    server 127.0.0.1:50051 max_fails=3 fail_timeout=10s;\n    keepalive 64;\n}\n\nserver {\n    listen 443 ssl http2;\n    server_name api.example.com;\n\n    # TLS ayarlar\u0131 (sertifikalar vs.)\n\n    # gRPC servis k\u00f6k\u00fc\n    location \/ {\n        grpc_pass grpc:\/\/grpc_backend;\n        grpc_read_timeout 3600s;\n        grpc_send_timeout 3600s;\n        grpc_set_header Host $host;\n    }\n}\n<\/code><\/pre>\n<p>gRPC taraf\u0131nda \u201changi direktif ne yapar\u201d diye tek tek bakmak isterseniz, resmi referans her zaman yolunuzu ayd\u0131nlat\u0131r. Ben de zaman zaman akl\u0131m\u0131 tazelemek i\u00e7in <a href=\"https:\/\/nginx.org\/en\/docs\/http\/ngx_http_grpc_module.html\" target=\"_blank\" rel=\"noopener nofollow\">Nginx\u2019in gRPC mod\u00fcl\u00fc belgelerine<\/a> d\u00f6n\u00fcp kontrol ediyorum.<\/p>\n<h2 id=\"section-5\"><span id=\"Cloudflare_Ayarlari_HTTP2_gRPC_ve_Sessiz_Timeouts\">Cloudflare Ayarlar\u0131: HTTP\/2, gRPC ve Sessiz Timeouts<\/span><\/h2>\n<p>Cloudflare, gRPC\u2019yi destekliyor. Panelde ilgili alan ad\u0131nda <strong>HTTP\/2<\/strong> a\u00e7\u0131k, gerekli gRPC se\u00e7ene\u011fi etkin ve kay\u0131t proxy\u2019li oldu\u011funda i\u015fler ak\u0131yor. \u00d6zellikle mobil a\u011flarda dalgal\u0131 ba\u011flant\u0131larda Cloudflare ara katman\u0131n\u0131n ritmi hayat kurtar\u0131yor. Ama \u015funu unutmay\u0131n: Cloudflare\u2019\u0131n kendi bekleme s\u00fcreleri ve s\u0131n\u0131rlar\u0131 var. Bu y\u00fczden Nginx\u2019te gereksiz k\u0131sa bir timeout, Cloudflare ile \u00e7ak\u0131\u015ft\u0131\u011f\u0131nda sessiz kesintilere davetiye \u00e7\u0131kar\u0131yor.<\/p>\n<p>Benim rutinim \u015fu: Da\u011f\u0131t\u0131mdan \u00f6nce Cloudflare panelinde gRPC\u2019nin a\u00e7\u0131k oldu\u011funu, SSL\/TLS modunun <strong>Full<\/strong> veya <strong>Full (Strict)<\/strong> seviyede oldu\u011funu, HTTP\/2\u2019nin aktif oldu\u011funu kontrol ederim. Sonra Nginx taraf\u0131nda hem okumay\u0131 hem yazmay\u0131 makul uzun tutar, upstream ba\u011flant\u0131 havuzunu \u0131s\u0131nd\u0131r\u0131r\u0131m. Cloudflare\u2019\u0131n gRPC detaylar\u0131na g\u00f6z atmak isterseniz <a href=\"https:\/\/developers.cloudflare.com\/grpc\/\" target=\"_blank\" rel=\"noopener nofollow\">resmi gRPC dok\u00fcmantasyonu<\/a> temiz anlat\u0131yor.<\/p>\n<p>WebSocket cephesinde de benzer bir durum var. \u00d6zellikle dayan\u0131ks\u0131z mobil a\u011flarda, Cloudflare katman\u0131 kopmalar\u0131 yumu\u015fat\u0131yor. Ama origin taraf\u0131n\u0131 sab\u0131rs\u0131z ayarlarsan\u0131z, \u201cneden \u00e7at diye d\u00fc\u015ft\u00fc?\u201d diye log bakars\u0131n\u0131z. WebSocket i\u00e7in Cloudflare notlar\u0131na tekrar bakmak isterseniz, ilgili ba\u015fl\u0131k burada: <a href=\"https:\/\/developers.cloudflare.com\/websockets\/\" target=\"_blank\" rel=\"noopener nofollow\">Cloudflare WebSocket belgeleri<\/a>.<\/p>\n<h2 id=\"section-6\"><span id=\"KeepAlive_Mantigi_Iki_Ucta_Ayni_Nefes\">Keep\u2011Alive Mant\u0131\u011f\u0131: \u0130ki U\u00e7ta Ayn\u0131 Nefes<\/span><\/h2>\n<p>Keep\u2011alive\u2019\u0131 \u201cayn\u0131 nefesi payla\u015fmak\u201d gibi d\u00fc\u015f\u00fcn\u00fcn. \u0130stemci Cloudflare ile nefes al\u0131p verirken, Cloudflare da origin\u2019le nefesi senkron tutuyor. Origin taraf\u0131nda her istekte yeniden TCP\/TLS kurulmazsa, gecikme d\u00fc\u015fer ve dalgal\u0131 anlarda daha az kopma ya\u015fars\u0131n\u0131z. Nginx\u2019te upstream havuzu i\u00e7in <strong>keepalive<\/strong> kullanmak, <strong>keepalive_timeout<\/strong> ve <strong>keepalive_requests<\/strong>\u2019i mant\u0131kl\u0131 seviyede tutmak, gidi\u015f\u2011geli\u015fi rahatlat\u0131yor.<\/p>\n<p>Bir noktay\u0131 \u00f6zellikle seviyorum: Ba\u011flant\u0131 havuzunu birka\u00e7 dakika \u00f6nceden \u0131s\u0131tmak. Yeni s\u00fcr\u00fcm\u00fc aya\u011fa kald\u0131r\u0131rken, upstream\u2019e yava\u015f\u00e7a trafik verip ba\u011flant\u0131lar\u0131 \u201cuyand\u0131r\u0131nca\u201d ilk ger\u00e7ek trafikte o tokat gibi hissedilen gecikmeyi ya\u015fam\u0131yorsunuz. Bu, \u00f6zellikle gRPC\u2019de ak\u0131\u015f ba\u015flat\u0131l\u0131rken \u00e7ok tatl\u0131 bir fark yarat\u0131yor.<\/p>\n<h2 id=\"section-7\"><span id=\"Kesintisiz_Dagitim_Reload_Drain_ve_BlueGreen\">Kesintisiz Da\u011f\u0131t\u0131m: Reload, Drain ve Blue\u2011Green<\/span><\/h2>\n<p>Deploy zaman\u0131 yakla\u015f\u0131rken ellerin terledi\u011fi oldu mu? \u00d6zellikle canl\u0131 WebSocket ba\u011flant\u0131lar\u0131 varken \u201cnginx -s reload\u201d demek insan\u0131n i\u00e7ini hoplat\u0131r. Nginx bu i\u015fi kibar yap\u0131yor asl\u0131nda. Yeni konfig\u00fcrasyonu y\u00fcklerken eski i\u015f\u00e7iler mevcut ba\u011flant\u0131lar\u0131 bitirip kenara \u00e7ekiliyor. Buna e\u015flik eden k\u00fc\u00e7\u00fck ama etkili ayar: <strong>worker_shutdown_timeout<\/strong>. Bu, i\u015f\u00e7ilerin mevcut ba\u011flant\u0131lar\u0131 nazik\u00e7e bo\u015faltmas\u0131na f\u0131rsat veriyor.<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">events {\n    worker_connections 4096;\n}\n\nhttp {\n    worker_shutdown_timeout 30s;\n\n    # ... geri kalan ayarlar\n}\n<\/code><\/pre>\n<p>Blue\u2011green benzeri bir ak\u0131\u015f i\u00e7in upstream\u2019i iki gruba ay\u0131r\u0131p a\u011f\u0131rl\u0131klar\u0131 y\u00f6netebilirsiniz. \u015e\u00f6yle bir iskelet, a\u011f\u0131rl\u0131\u011f\u0131 kademeli de\u011fi\u015ftirerek s\u0131f\u0131ra yak\u0131n riskle ge\u00e7i\u015f yapman\u0131z\u0131 sa\u011flar:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">upstream grpc_backend {\n    zone grpc_backend 64k;\n    server 10.0.0.10:50051 weight=1 max_fails=2 fail_timeout=5s;  # Blue\n    server 10.0.0.11:50051 weight=0 max_fails=2 fail_timeout=5s;  # Green\n    keepalive 64;\n}\n<\/code><\/pre>\n<p>Yeni s\u00fcr\u00fcm (Green) haz\u0131r olunca a\u011f\u0131rl\u0131\u011f\u0131 yava\u015f yava\u015f art\u0131r\u0131rs\u0131n\u0131z. \u201cReload\u201d ile konfig\u00fcrasyonu nazik\u00e7e yeniler, gelen ak\u0131\u015f\u0131 yeni s\u00fcr\u00fcme kayd\u0131r\u0131rs\u0131n\u0131z. Bir sorun olursa geri d\u00f6n\u00fc\u015f de ayn\u0131 h\u0131zda olur. Ben ge\u00e7i\u015f s\u0131ras\u0131nda hem <strong>origin loglar\u0131n\u0131<\/strong> hem de Cloudflare analytics ekran\u0131n\u0131 yan yana a\u00e7may\u0131 al\u0131\u015fkanl\u0131k edindim. B\u00f6ylece ufak dalgalar\u0131 an\u0131nda g\u00f6r\u00fcp frenleyebiliyorum.<\/p>\n<h2 id=\"section-8\"><span id=\"Gercek_Bir_Senaryo_Sohbet_Sunucusunu_Geceden_Canliya_Almak\">Ger\u00e7ek Bir Senaryo: Sohbet Sunucusunu Geceden Canl\u0131ya Almak<\/span><\/h2>\n<p>Bir gece sohbet sunucusunu yeni s\u00fcr\u00fcme alaca\u011f\u0131z. M\u00fc\u015fteriler uyurken bile i\u00e7eride sohbet var; yani \u201ctrafik yokken al\u0131r\u0131z\u201d l\u00fcks\u00fc yok. \u00d6nce yeni s\u00fcr\u00fcm\u00fc ayr\u0131 bir upstream\u2019e koyduk. Kendi i\u00e7inde sa\u011fl\u0131k kontrollerini ge\u00e7ince, ba\u011flant\u0131 havuzunu \u0131s\u0131tt\u0131k. Ard\u0131ndan a\u011f\u0131rl\u0131\u011f\u0131 y\u00fczdeyle de\u011fil, \u201cbiraz\u201d ve \u201cbiraz daha\u201d gibi k\u00fc\u00e7\u00fck ad\u0131mlarla art\u0131rd\u0131k. Loglarda garip bir \u015fey g\u00f6r\u00fcnce a\u011f\u0131rl\u0131\u011f\u0131 geri \u00e7ektik, k\u00fc\u00e7\u00fck bir d\u00fczeltme yapt\u0131k ve tekrar y\u00fckselttik.<\/p>\n<p>WebSocket taraf\u0131nda proxy tamponlamas\u0131n\u0131 kapatmak ve uzun <strong>read timeout<\/strong> vermek g\u00fczel sonu\u00e7 verdi. gRPC taraf\u0131nda ise ak\u0131\u015f\u0131n ba\u015f\u0131nda hafif bir gecikme g\u00f6rd\u00fck, bunu da upstream keep\u2011alive havuzunu b\u00fcy\u00fcterek yumu\u015fatt\u0131k. En son \u201creload\u201d ile t\u00fcm s\u00fcreci kal\u0131c\u0131 hale getirdik. Kimse kopma hissetmedi, sabah kahvelerimizi rahat i\u00e7tik.<\/p>\n<h2 id=\"section-9\"><span id=\"Sorun_Giderme_Loglar_Izler_ve_Ufak_Sinyaller\">Sorun Giderme: Loglar, \u0130zler ve Ufak Sinyaller<\/span><\/h2>\n<p>Do\u011frusu, sessiz kopmalar en zor olanlar. Loglarda kocaman hata g\u00f6rmezsiniz ama kullan\u0131c\u0131 \u201cmesaj\u0131m niye gitmedi?\u201d der. B\u00f6yle anlarda iki ara\u00e7 seti \u00e7ok yard\u0131mc\u0131 oldu. \u0130lki, merkezi loglar ve okunabilir seviyede <strong>timeout\/disk ba\u011flant\u0131<\/strong> mesajlar\u0131. \u0130kincisi ise isteklerin i\u00e7inde ufak izler ta\u015f\u0131mak. \u0130kisinin birle\u015fimi do\u011fru yeri i\u015faret ediyor.<\/p>\n<p>Merkezi loglama taraf\u0131n\u0131 kurmak isterseniz, ad\u0131m ad\u0131m notlar\u0131 \u015fu yaz\u0131da toplam\u0131\u015ft\u0131m: <a href=\"https:\/\/www.dchost.com\/blog\/vps-log-yonetimi-nasil-rayina-oturur-grafana-loki-promtail-ile-merkezi-loglama-tutma-sureleri-ve-alarm-kurallari\/\" target=\"_blank\" rel=\"noopener\">Loki ile merkezi loglama kurulumunu<\/a> buradan inceleyebilirsiniz. \u0130zleri u\u00e7tan uca g\u00f6t\u00fcrmek, \u00f6zellikle gRPC\u2019de \u00e7a\u011fr\u0131n\u0131n ak\u0131\u015f\u0131nda neler ya\u015fand\u0131\u011f\u0131n\u0131 g\u00f6rmek i\u00e7in nefis. Bunun i\u00e7in de <a href=\"https:\/\/www.dchost.com\/blog\/opentelemetry-ile-izlenebilirlik-laravel-ve-node-jste-jaeger-tempoya-uctan-uca-izler-nasil-kurulur\/\" target=\"_blank\" rel=\"noopener\">OpenTelemetry ile u\u00e7tan uca izler<\/a> yaz\u0131s\u0131ndaki \u00f6rnekler g\u00fcndelik i\u015fte birebir \u00e7al\u0131\u015f\u0131yor.<\/p>\n<p>Bir pratik ipucu daha: gRPC \u00e7a\u011fr\u0131lar\u0131n\u0131 u\u00e7tan uca test ederken canl\u0131 trafi\u011fi rahats\u0131z etmeden k\u00fc\u00e7\u00fck sa\u011fl\u0131k istekleri kullan\u0131n. WebSocket\u2019te ise d\u00fc\u015f\u00fck hacimli ping\/pong mekanizmas\u0131, pasif durumlarda ba\u011flant\u0131lar\u0131n uykuya dalmas\u0131n\u0131 engelliyor. Bu sinyallerin aral\u0131\u011f\u0131n\u0131 \u00e7ok s\u0131k ya da \u00e7ok seyrek tutmadan, \u201chatlar \u00e7al\u0131\u015f\u0131yor mu?\u201d diye yoklayan bir ritme oturtmak sorunlar\u0131 daha loga d\u00fc\u015fmeden yakal\u0131yor.<\/p>\n<h2 id=\"section-10\"><span id=\"Guvenlik_ve_Dengeli_Sinirlar\">G\u00fcvenlik ve Dengeli S\u0131n\u0131rlar<\/span><\/h2>\n<p>Uzun ya\u015fayan ba\u011flant\u0131larda g\u00fcvenlik konusu atlan\u0131nca, ileride can s\u0131k\u0131c\u0131 s\u00fcrprizlere davetiye \u00e7\u0131k\u0131yor. \u0130stemci ile sunucu aras\u0131ndaki kimlik do\u011frulama, \u00f6zellikle i\u00e7 trafi\u011fi korumak istedi\u011finizde, i\u015fi bir \u00fcst seviyeye ta\u015f\u0131yor. Ben bu noktada mTLS\u2019i seviyorum; y\u00f6netim aray\u00fczlerinde ve servis\u2011servis konu\u015fmalarda ger\u00e7ekten i\u015f g\u00f6r\u00fcyor. Detaylar\u0131 ad\u0131m ad\u0131m g\u00f6rmek isterseniz, \u015fu rehber epey i\u015ftah a\u00e7\u0131c\u0131: <a href=\"https:\/\/www.dchost.com\/blog\/nginx-ve-caddyde-mtls-nasil-kurulur-mikroservislerde-sertifika-dogrulamanin-tatli-sirlari\/\" target=\"_blank\" rel=\"noopener\">mTLS ile mikroservis do\u011frulamas\u0131n\u0131 nas\u0131l kurdu\u011fumu<\/a> burada anlatt\u0131m.<\/p>\n<p>A\u011f taraf\u0131nda da minik dokunu\u015flar b\u00fcy\u00fck fark yarat\u0131yor. Sadece gereken portlar\u0131 a\u00e7mak, oran s\u0131n\u0131rlamay\u0131 nazik\u00e7e d\u00fczenlemek ve beklenmeyen sald\u0131r\u0131 dalgalar\u0131nda otomatik frenlemek g\u00fcnl\u00fck huzurun gizli s\u0131rr\u0131 gibi. Ad\u0131m ad\u0131m kurmak isterseniz, <a href=\"https:\/\/www.dchost.com\/blog\/nftables-ile-vps-guvenlik-duvari-rehberi-rate-limit-port-knocking-ve-ipv6-kurallari-nasil-tatli-tatli-kurulur\/\" target=\"_blank\" rel=\"noopener\">nftables ile g\u00fcvenlik duvar\u0131 kurallar\u0131n\u0131<\/a> anlatt\u0131\u011f\u0131m notlar iyi bir ba\u015flang\u0131\u00e7 oluyor.<\/p>\n<h2 id=\"section-11\"><span id=\"Cloudflare_Uzerinden_gRPC_ve_WebSockette_Ince_Ayar\">Cloudflare \u00dczerinden gRPC ve WebSocket\u2019te \u0130nce Ayar<\/span><\/h2>\n<p>Cloudflare panelindeki k\u00fc\u00e7\u00fck anahtarlar bazen kader \u00e7iziyor. DNS kayd\u0131n\u0131 proxy\u2019li tutmak, HTTP\/2\u2019yi a\u00e7\u0131k b\u0131rakmak ve gRPC \u00f6zelli\u011fini etkinle\u015ftirmek ak\u0131\u015f\u0131n temelini kuruyor. Bu \u00fc\u00e7l\u00fc var diye her \u015fey sorunsuz mu? Neredeyse. As\u0131l fark, origin taraf\u0131ndaki sab\u0131rl\u0131 davran\u0131\u015f. Nginx\u2019te zaman a\u015f\u0131m\u0131 de\u011ferlerini \u201ci\u015finizin do\u011fas\u0131na\u201d g\u00f6re ayarlay\u0131n: canl\u0131 destek konu\u015fmas\u0131 ile k\u0131sa s\u00fcreli bildirim ak\u0131\u015f\u0131n\u0131n ritmi ayn\u0131 de\u011fil. Birinde uzun nefes, di\u011ferinde daha h\u0131zl\u0131 ama yine dengeli nefes gerekiyor.<\/p>\n<p>Cloudflare\u2019\u0131n belgeleri g\u00fcncel ve pratik. Bir ayar de\u011fi\u015fti mi, bir limit g\u00fcncellendi mi, oradan ilk elden g\u00f6r\u00fcrs\u00fcn\u00fcz. Ba\u015flang\u0131\u00e7 noktas\u0131 olarak \u015funu i\u015faretleyeyim; WebSocket i\u00e7in <a href=\"https:\/\/developers.cloudflare.com\/websockets\/\" target=\"_blank\" rel=\"noopener nofollow\">Cloudflare WebSocket belgeleri<\/a>, gRPC i\u00e7in de <a href=\"https:\/\/developers.cloudflare.com\/grpc\/\" target=\"_blank\" rel=\"noopener nofollow\">Cloudflare gRPC dok\u00fcman\u0131<\/a> i\u015finizi g\u00f6r\u00fcr.<\/p>\n<h2 id=\"section-12\"><span id=\"Nginx_Reloadi_Guvenle_Almak_Icin_Kucuk_Bir_Rutin\">Nginx Reload\u2019\u0131 G\u00fcvenle Almak \u0130\u00e7in K\u00fc\u00e7\u00fck Bir Rutin<\/span><\/h2>\n<p>Ben da\u011f\u0131t\u0131m \u00f6ncesi k\u0131sa bir rit\u00fcel yap\u0131yorum. \u00d6nce yeni upstream\u2019i pasif bi\u00e7imde aya\u011fa kald\u0131r\u0131yorum. Smoke testleri ge\u00e7ince, birka\u00e7 istekle havuzu \u0131s\u0131t\u0131yorum. Ard\u0131ndan a\u011f\u0131rl\u0131\u011f\u0131 k\u00fc\u00e7\u00fck ad\u0131mlarla art\u0131r\u0131yorum. Her ad\u0131mda loglara bak\u0131yorum, Cloudflare analytics\u2019i de yan sekmede a\u00e7\u0131k tutuyorum. \u0130\u00e7im rahatsa \u201cnginx -s reload\u201d veya \u201csystemctl reload nginx\u201d diyorum. Eski i\u015f\u00e7ilerin ba\u011flant\u0131lar\u0131 bitirmesine izin veren <strong>worker_shutdown_timeout<\/strong> zaten ba\u015fta ayarl\u0131.<\/p>\n<p>gRPC\u2019de ba\u011flant\u0131lar\u0131n ak\u0131\u015f\u0131n\u0131 kesmemek i\u00e7in de istemci taraf\u0131nda k\u0131sa bir tekrar deneme mant\u0131\u011f\u0131 b\u0131rak\u0131yorum. B\u00f6ylece arada tek t\u00fck d\u00fc\u015fen ak\u0131\u015flar kullan\u0131c\u0131 fark etmeden yeniden ba\u011flan\u0131yor. Bu tekrar deneme i\u015fini \u00e7ok agresif de\u011fil, nazik bir aral\u0131kla yapmak iyi sonu\u00e7 veriyor. Aksi takdirde k\u00fc\u00e7\u00fck bir dalga tsunamiye d\u00f6n\u00fc\u015febiliyor.<\/p>\n<h2 id=\"section-13\"><span id=\"Ileri_Dusunceler_Izlenebilirlik_ve_Runbooklar\">\u0130leri D\u00fc\u015f\u00fcnceler: \u0130zlenebilirlik ve Runbook\u2019lar<\/span><\/h2>\n<p>\u0130\u015finiz b\u00fcy\u00fcd\u00fck\u00e7e, \u201ckim neden koptu?\u201d sorusuna cevap bulmak i\u00e7in sadece log yetmiyor. G\u00f6z\u00fcn\u00fcz\u00fcn \u00f6n\u00fcnden ge\u00e7en bir zaman \u00e7izgisi laz\u0131m. Ben burada izleri ve metrikleri ayn\u0131 hikayede birle\u015ftirmeyi seviyorum. Node ya da PHP fark etmiyor, ak\u0131\u015f\u0131n ba\u015f\u0131ndan sonuna kadar g\u00f6r\u00fcn\u00fcrl\u00fck rahatlat\u0131yor. \u0130lham almak isterseniz, <a href=\"https:\/\/www.dchost.com\/blog\/opentelemetry-ile-izlenebilirlik-laravel-ve-node-jste-jaeger-tempoya-uctan-uca-izler-nasil-kurulur\/\" target=\"_blank\" rel=\"noopener\">OpenTelemetry ile u\u00e7tan uca izler<\/a> yaz\u0131s\u0131 bunu canl\u0131 canl\u0131 anlat\u0131yor.<\/p>\n<p>Bir de runbook\u2019lar. Gece yar\u0131s\u0131 kopma oldu\u011funda \u201changi s\u0131rayla neye bakaca\u011f\u0131m?\u201d sorusuna cevab\u0131n\u0131z haz\u0131r olmal\u0131. K\u00fc\u00e7\u00fck bir kontrol listesi, Cloudflare paneline nereden bak\u0131laca\u011f\u0131, Nginx loglar\u0131nda hangi anahtar kelimelerin aranaca\u011f\u0131 ve gerekiyorsa ge\u00e7ici geri d\u00f6n\u00fc\u015f plan\u0131\u2026 Bunlar konu\u015ftu\u011fumuz her \u015feyi g\u00fcvenle tekrar edilebilir hale getiriyor.<\/p>\n<h2 id=\"section-14\"><span id=\"Hizli_Testler_Kucuk_Araclar_Buyuk_Guven\">H\u0131zl\u0131 Testler: K\u00fc\u00e7\u00fck Ara\u00e7lar, B\u00fcy\u00fck G\u00fcven<\/span><\/h2>\n<p>Sahada \u015funu fark ettim: De\u011fi\u015fiklikten sonra her \u015feyi u\u00e7tan uca test eden ufak komutlar huzur veriyor. WebSocket i\u00e7in basit bir istemci ile ba\u011flan\u0131p birka\u00e7 dakika ping\/pong yapmak, gRPC i\u00e7in k\u00fc\u00e7\u00fck bir test \u00e7a\u011fr\u0131s\u0131n\u0131 pe\u015f pe\u015fe \u00e7al\u0131\u015ft\u0131rmak ve araya Cloudflare varken davran\u0131\u015f\u0131 izlemek\u2026 Hepsi bir araya gelince \u201ctamam, olabilir\u201d diyorsunuz. Teknik derinlikte bo\u011fulmadan, pratik do\u011frulama ad\u0131mlar\u0131 i\u015finizi b\u00fcy\u00fct\u00fcyor.<\/p>\n<p>gRPC ayarlar\u0131n\u0131 incelerken Nginx\u2019in resmi referans\u0131na d\u00f6nmek iyi bir al\u0131\u015fkanl\u0131k. Arad\u0131\u011f\u0131n\u0131z bir direktifin ayr\u0131nt\u0131s\u0131 i\u00e7in <a href=\"https:\/\/nginx.org\/en\/docs\/http\/ngx_http_grpc_module.html\" target=\"_blank\" rel=\"noopener nofollow\">gRPC mod\u00fcl\u00fcn\u00fcn belgeleri<\/a> h\u0131zl\u0131ca fikri netle\u015ftiriyor. Cloudflare taraf\u0131nda da de\u011fi\u015fiklik oldu\u011funda, ilgili sayfalar g\u00fcncellemeleri a\u00e7\u0131k\u00e7a g\u00f6steriyor.<\/p>\n<h2 id=\"section-15\"><span id=\"Kapanis_Ufak_Dokunuslarla_Buyuk_Huzur\">Kapan\u0131\u015f: Ufak Dokunu\u015flarla B\u00fcy\u00fck Huzur<\/span><\/h2>\n<p>Toparlayal\u0131m. Cloudflare ile WebSocket ve gRPC trafi\u011fini Nginx \u00fczerinden yay\u0131nlarken as\u0131l mesele, katmanlar\u0131n nefesini uyumlamak. Upgrade ba\u015fl\u0131klar\u0131 do\u011fru ge\u00e7ecek, timeout\u2019lar sab\u0131rl\u0131 olacak, keep\u2011alive havuzu ak\u0131\u015f\u0131 yumu\u015fatacak. Deploy s\u0131ras\u0131nda reload nazik\u00e7e yap\u0131l\u0131p eski i\u015f\u00e7ilere veda f\u0131rsat\u0131 verilecek. Arka planda ise loglar, izler ve minik sa\u011fl\u0131k sinyalleri i\u015fin nabz\u0131n\u0131 tutacak.<\/p>\n<p>Pratik bir tavsiye seti b\u0131rakay\u0131m: WebSocket\u2019te proxy tamponlamas\u0131n\u0131 kapat\u0131n, upgrade ba\u015fl\u0131klar\u0131n\u0131 unutmay\u0131n. gRPC\u2019de HTTP\/2\u2019yi dinleyin, read\/send timeout\u2019lar\u0131 i\u015fin do\u011fas\u0131na g\u00f6re ayarlay\u0131n. Cloudflare panelinde HTTP\/2 ve gRPC\u2019nin a\u00e7\u0131k oldu\u011funa eminsiniz. Upstream keep\u2011alive ile ba\u011flant\u0131 havuzunu \u0131s\u0131t\u0131n, a\u011f\u0131rl\u0131klar\u0131 k\u00fc\u00e7\u00fck ad\u0131mlarla de\u011fi\u015ftirin ve reload\u2019\u0131 sakince al\u0131n. G\u00fcvenlik i\u00e7in mTLS ve temel firewall kurallar\u0131yla ak\u0131\u015f\u0131 sa\u011flamla\u015ft\u0131r\u0131n. Umar\u0131m bu yaz\u0131 elinizi rahatlatt\u0131. Bir dahaki yaz\u0131da g\u00f6r\u00fc\u015fmek \u00fczere, bol stabil ba\u011flant\u0131lar dilerim.<\/p>\n<\/div>","protected":false},"excerpt":{"rendered":"<p>\u0130&ccedil;indekiler1 Ofiste Bir Ak\u015fam: Sessizce D\u00fc\u015fen Ba\u011flant\u0131lar2 Cloudflare, WebSocket ve gRPC \u00dc\u00e7l\u00fcs\u00fc Neden Nazl\u0131?3 Nginx\u2019te WebSocket: Upgrade, Timeout ve Keep\u2011Alive4 Nginx\u2019te gRPC: HTTP\/2, Ba\u015fl\u0131klar ve Stabil Ak\u0131\u015f5 Cloudflare Ayarlar\u0131: HTTP\/2, gRPC ve Sessiz Timeouts6 Keep\u2011Alive Mant\u0131\u011f\u0131: \u0130ki U\u00e7ta Ayn\u0131 Nefes7 Kesintisiz Da\u011f\u0131t\u0131m: Reload, Drain ve Blue\u2011Green8 Ger\u00e7ek Bir Senaryo: Sohbet Sunucusunu Geceden Canl\u0131ya Almak9 Sorun [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":1675,"comment_status":"","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[26],"tags":[],"class_list":["post-1674","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-teknoloji"],"_links":{"self":[{"href":"https:\/\/www.dchost.com\/blog\/wp-json\/wp\/v2\/posts\/1674","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.dchost.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.dchost.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.dchost.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.dchost.com\/blog\/wp-json\/wp\/v2\/comments?post=1674"}],"version-history":[{"count":0,"href":"https:\/\/www.dchost.com\/blog\/wp-json\/wp\/v2\/posts\/1674\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.dchost.com\/blog\/wp-json\/wp\/v2\/media\/1675"}],"wp:attachment":[{"href":"https:\/\/www.dchost.com\/blog\/wp-json\/wp\/v2\/media?parent=1674"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.dchost.com\/blog\/wp-json\/wp\/v2\/categories?post=1674"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.dchost.com\/blog\/wp-json\/wp\/v2\/tags?post=1674"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}