{"id":1983,"date":"2025-11-17T20:47:37","date_gmt":"2025-11-17T17:47:37","guid":{"rendered":"https:\/\/www.dchost.com\/blog\/vpste-canary-dagitimi-nasil-tatli-tatli-kurulur-nginx-agirlikli-yonlendirme-saglik-kontrolu-ve-guvenli-rollback\/"},"modified":"2025-11-17T20:47:37","modified_gmt":"2025-11-17T17:47:37","slug":"vpste-canary-dagitimi-nasil-tatli-tatli-kurulur-nginx-agirlikli-yonlendirme-saglik-kontrolu-ve-guvenli-rollback","status":"publish","type":"post","link":"https:\/\/www.dchost.com\/blog\/vpste-canary-dagitimi-nasil-tatli-tatli-kurulur-nginx-agirlikli-yonlendirme-saglik-kontrolu-ve-guvenli-rollback\/","title":{"rendered":"VPS\u2019te Canary Da\u011f\u0131t\u0131m\u0131 Nas\u0131l Tatl\u0131 Tatl\u0131 Kurulur? Nginx A\u011f\u0131rl\u0131kl\u0131 Y\u00f6nlendirme, Sa\u011fl\u0131k Kontrol\u00fc ve G\u00fcvenli Rollback"},"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=\"#Giris_Kucuk_bir_surum_buyuk_bir_nefes\"><span class=\"toc_number toc_depth_1\">1<\/span> Giri\u015f: K\u00fc\u00e7\u00fck bir s\u00fcr\u00fcm, b\u00fcy\u00fck bir nefes<\/a><\/li><li><a href=\"#Canary_dagitimi_tam_olarak_ne_Neden_VPSte_isleri_kolaylastirir\"><span class=\"toc_number toc_depth_1\">2<\/span> Canary da\u011f\u0131t\u0131m\u0131 tam olarak ne? Neden VPS\u2019te i\u015fleri kolayla\u015ft\u0131r\u0131r?<\/a><\/li><li><a href=\"#Nginx_ile_agirlikli_yonlendirme_nasil_kurulur\"><span class=\"toc_number toc_depth_1\">3<\/span> Nginx ile a\u011f\u0131rl\u0131kl\u0131 y\u00f6nlendirme nas\u0131l kurulur?<\/a><ul><li><a href=\"#Hedefli_test_Cookie_ile_sadece_sen_ve_ekibin_gorsun\"><span class=\"toc_number toc_depth_2\">3.1<\/span> Hedefli test: Cookie ile sadece sen ve ekibin g\u00f6rs\u00fcn<\/a><\/li><li><a href=\"#Agirlikli_trafik_Yuzde_hesaplariyla_degil_ayar_dugmesiyle\"><span class=\"toc_number toc_depth_2\">3.2<\/span> A\u011f\u0131rl\u0131kl\u0131 trafik: Y\u00fczde hesaplar\u0131yla de\u011fil, ayar d\u00fc\u011fmesiyle<\/a><\/li><\/ul><\/li><li><a href=\"#Saglik_kontrolu_Pasif_aktif_ve_loglarin_gozu\"><span class=\"toc_number toc_depth_1\">4<\/span> Sa\u011fl\u0131k kontrol\u00fc: Pasif, aktif ve log\u2019lar\u0131n g\u00f6z\u00fc<\/a><ul><li><a href=\"#Uygulamanin_agzindan_iyiyim_demesi\"><span class=\"toc_number toc_depth_2\">4.1<\/span> Uygulaman\u0131n a\u011fz\u0131ndan \u201ciyiyim\u201d demesi<\/a><\/li><li><a href=\"#Loglarda_canaryyi_boyamak\"><span class=\"toc_number toc_depth_2\">4.2<\/span> Log\u2019larda canary\u2019yi boyamak<\/a><\/li><\/ul><\/li><li><a href=\"#Guvenli_rollback_Geri_donus_yolunu_bastan_cizmek\"><span class=\"toc_number toc_depth_1\">5<\/span> G\u00fcvenli rollback: Geri d\u00f6n\u00fc\u015f yolunu ba\u015ftan \u00e7izmek<\/a><ul><li><a href=\"#Tek_komutla_guvenlik_canaryctl_ramp-up_ve_rollback\"><span class=\"toc_number toc_depth_2\">5.1<\/span> Tek komutla g\u00fcvenlik: canaryctl ramp-up ve rollback<\/a><\/li><\/ul><\/li><li><a href=\"#Aksam_plani_Kucuk_bir_surumu_canary_ile_yayina_alma\"><span class=\"toc_number toc_depth_1\">6<\/span> Ak\u015fam plan\u0131: K\u00fc\u00e7\u00fck bir s\u00fcr\u00fcm\u00fc canary ile yay\u0131na alma<\/a><\/li><li><a href=\"#Ek_notlar_TLS_reload_ve_kucuk_tehlikeler\"><span class=\"toc_number toc_depth_1\">7<\/span> Ek notlar: TLS, reload ve k\u00fc\u00e7\u00fck tehlikeler<\/a><\/li><li><a href=\"#Kapanis_Canary_kucuk_cesur_adimlarin_guvenligi\"><span class=\"toc_number toc_depth_1\">8<\/span> Kapan\u0131\u015f: Canary, k\u00fc\u00e7\u00fck cesur ad\u0131mlar\u0131n g\u00fcvenli\u011fi<\/a><\/li><\/ul><\/div>\n<h2 id=\"section-1\"><span id=\"Giris_Kucuk_bir_surum_buyuk_bir_nefes\">Giri\u015f: K\u00fc\u00e7\u00fck bir s\u00fcr\u00fcm, b\u00fcy\u00fck bir nefes<\/span><\/h2>\n<p>Hi\u00e7 ak\u015fam \u00fczeri k\u00fc\u00e7\u00fck bir d\u00fczeltme g\u00f6ndereyim derken, bir anda beklenmedik bir dalgalanmayla t\u00fcm trafi\u011fi etkiledi\u011fin oldu mu? Ben bir keresinde, minik bir hatay\u0131 kapatay\u0131m diye aceleyle g\u00f6nderdi\u011fim s\u00fcr\u00fcm y\u00fcz\u00fcnden, geceyi log\u2019lar\u0131n ba\u015f\u0131nda kahveyle ge\u00e7irmi\u015ftim. O g\u00fcn karar verdim: \u00dcretimi \u015fansa b\u0131rakmak yok, \u00f6nce ufak bir kitleye g\u00f6ster, g\u00f6nl\u00fcn rahat etsin. \u0130\u015fte canary da\u011f\u0131t\u0131m\u0131 tam olarak bu rahatl\u0131\u011f\u0131n ad\u0131. Yeni s\u00fcr\u00fcm\u00fcn \u00f6nce ufak bir k\u0131sma g\u00f6r\u00fcn\u00fcr, bir s\u00fcre g\u00f6zlersin, i\u015fler yolundaysa yava\u015f yava\u015f herkese a\u00e7ars\u0131n.<\/p>\n<p>Bu yaz\u0131da <a href=\"https:\/\/www.dchost.com\/tr\/vps\">VPS<\/a> \u00fczerinde canary da\u011f\u0131t\u0131m\u0131n\u0131, Nginx ile a\u011f\u0131rl\u0131kl\u0131 y\u00f6nlendirmeyi, pratik bir sa\u011fl\u0131k kontrol\u00fc yakla\u015f\u0131m\u0131n\u0131 ve tek tu\u015fla g\u00fcvenli geri d\u00f6n\u00fc\u015f (rollback) d\u00fczenini ad\u0131m ad\u0131m anlataca\u011f\u0131m. Masada abart\u0131 yok, tablo yok, uzun \u201ckan\u0131t\u201d listeleri de yok; ger\u00e7ek hayatta i\u015fe yarayan, ak\u0131\u015fkan ve kolayca hayata ge\u00e7irilebilen bir kurgu var. Hepimizin sevdi\u011fi o \u201caz risk, fazla kontrol\u201d halini birlikte kuraca\u011f\u0131z. Hadi ba\u015flayal\u0131m.<\/p>\n<h2 id=\"section-2\"><span id=\"Canary_dagitimi_tam_olarak_ne_Neden_VPSte_isleri_kolaylastirir\">Canary da\u011f\u0131t\u0131m\u0131 tam olarak ne? Neden VPS\u2019te i\u015fleri kolayla\u015ft\u0131r\u0131r?<\/span><\/h2>\n<p>Canary da\u011f\u0131t\u0131m\u0131, yeni s\u00fcr\u00fcm\u00fc herkesin \u00f6n\u00fcne bir anda koymak yerine, trafi\u011fin k\u00fc\u00e7\u00fck bir y\u00fczdesine g\u00f6stermektir. D\u00fc\u015f\u00fcn ki d\u00fckk\u00e2n\u0131na yeni bir vitrin yerle\u015ftireceksin; \u00f6nce bir k\u00f6\u015fede dener, yoldan ge\u00e7en birka\u00e7 m\u00fc\u015fterinin bak\u0131\u015f\u0131n\u0131 izler, yerinde mi de\u011fil mi koklars\u0131n. Be\u011feniler iyi, geri bildirimler temizse yava\u015f yava\u015f t\u00fcm vitrine yayars\u0131n. Bu kadar basit ve bu kadar insan gibi bir yakla\u015f\u0131m.<\/p>\n<p>VPS taraf\u0131nda bunun g\u00fczelli\u011fi, kontrol\u00fcn sende olmas\u0131nda. Nginx ile gelen trafi\u011fi nas\u0131l b\u00f6lece\u011fine sen karar veriyorsun. \u0130stersen ekibindeki birka\u00e7 ki\u015fi i\u00e7in bir \u00e7erezle (cookie) canary\u2019yi zorunlu k\u0131l, istersen a\u011f\u0131rl\u0131klar\u0131 de\u011fi\u015ftirerek y\u00fczdeyi yumu\u015fak\u00e7a y\u00fckselt. Bir hata kokusu al\u0131rsan, a\u011f\u0131rl\u0131\u011f\u0131 s\u0131f\u0131ra \u00e7ekersin, konu kapan\u0131r. \u00dcstelik bunu yaparken sistemin nefesini kesmiyorsun, trafik do\u011fal ak\u0131\u015f\u0131na devam ediyor. K\u0131sacas\u0131, \u201ck\u00fc\u00e7\u00fck ad\u0131mlar, b\u00fcy\u00fck g\u00fcven.\u201d<\/p>\n<p>Mesela \u015f\u00f6yle d\u00fc\u015f\u00fcn\u00fcn: Mutfakta yeni bir sos deniyorsun. \u0130lk ka\u015f\u0131\u011f\u0131 kendin tadars\u0131n, sonra arkada\u015f\u0131na uzat\u0131rs\u0131n, ard\u0131ndan masadakilere ikram edersin. Kimsenin damak tad\u0131n\u0131 riske atmadan, sosa da haks\u0131zl\u0131k etmeden ilerlersin. Canary\u2019nin ruhu bundan ibaret.<\/p>\n<h2 id=\"section-3\"><span id=\"Nginx_ile_agirlikli_yonlendirme_nasil_kurulur\">Nginx ile a\u011f\u0131rl\u0131kl\u0131 y\u00f6nlendirme nas\u0131l kurulur?<\/span><\/h2>\n<p>\u0130\u015fin kalbi Nginx\u2019te. Trafi\u011fi iki havuza ay\u0131raca\u011f\u0131z: stable ve canary. Stable mevcut s\u00fcr\u00fcm, canary yeni s\u00fcr\u00fcm. Y\u00fck dengeleyici mant\u0131\u011f\u0131yla d\u00fc\u015f\u00fcn; iki farkl\u0131 backend var, Nginx onlara a\u011f\u0131rl\u0131klar\u0131na g\u00f6re istekleri payla\u015ft\u0131r\u0131yor. A\u011f\u0131rl\u0131k artt\u0131k\u00e7a daha \u00e7ok istek gidiyor. <a href=\"https:\/\/nginx.org\/en\/docs\/http\/ngx_http_upstream_module.html\" rel=\"nofollow noopener\" target=\"_blank\">Nginx\u2019in upstream ve weight y\u00f6nergeleri<\/a> bu i\u015fi \u00e7ok temiz hallediyor.<\/p>\n<p>Bir de kibar bir hilemiz var: Ekip arkada\u015flar\u0131n\u0131n taray\u0131c\u0131s\u0131na minik bir cookie b\u0131rakarak, \u00f6nce yaln\u0131zca onlar\u0131n yeni s\u00fcr\u00fcm\u00fc g\u00f6rmesini sa\u011flayaca\u011f\u0131z. B\u00f6ylece test i\u00e7in staging\u2019e muhta\u00e7 kalmadan, ger\u00e7ek kullan\u0131c\u0131 trafi\u011finin kenar\u0131nda y\u00fcr\u00fcyen bir mini sahne kuruyoruz. Bu da bize hem h\u0131z hem de ger\u00e7ek ortam kokusu kazand\u0131r\u0131yor. Hadi ayarlar\u0131 konu\u015fal\u0131m.<\/p>\n<h3><span id=\"Hedefli_test_Cookie_ile_sadece_sen_ve_ekibin_gorsun\">Hedefli test: Cookie ile sadece sen ve ekibin g\u00f6rs\u00fcn<\/span><\/h3>\n<p>\u00d6nce cookie tabanl\u0131 y\u00f6nlendirmeyi kural\u0131m. Bu k\u0131s\u0131mda, canary=1 \u00e7erezi olanlar do\u011frudan canary backend\u2019ine gidecek. Di\u011ferleri hen\u00fcz a\u011f\u0131rl\u0131kl\u0131 ortama d\u00fc\u015fecek, yani normal kullan\u0131c\u0131lar hemen etkilenmeyecek.<\/p>\n<pre class=\"language-python line-numbers\"><code class=\"language-python\"># \/etc\/nginx\/conf.d\/app.conf (\u00f6rnek)\n\nupstream app_stable {\n    server 127.0.0.1:8080 max_fails=3 fail_timeout=10s;\n}\n\nupstream app_canary {\n    server 127.0.0.1:9080 max_fails=3 fail_timeout=10s;\n}\n\n# Canary cookie var m\u0131, yok mu?\nmap $cookie_canary $upstream_pool {\n    default   &quot;weighted&quot;;   # cookie yoksa a\u011f\u0131rl\u0131kl\u0131 havuz devrede\n    &quot;1&quot;      &quot;canary&quot;;     # cookie=1 ise direkt canary\n}\n\n# A\u011f\u0131rl\u0131kl\u0131 havuz (birazdan include edece\u011fiz)\n# \/etc\/nginx\/includes\/app_weights.conf dosyas\u0131nda tan\u0131mlayaca\u011f\u0131z\n\n# $upstream_pool de\u011ferine g\u00f6re hedef upstream ismi se\u00e7\nmap $upstream_pool $backend_upstream {\n    canary   app_canary;\n    default  app_weighted;\n}\n\nserver {\n    listen 80;\n    server_name example.com;\n\n    # \u0130\u00e7eriden denemek i\u00e7in h\u0131zl\u0131 bir anahtar: ?canary=1 ile cookie b\u0131rak\n    if ($arg_canary = &quot;1&quot;) {\n        add_header Set-Cookie &quot;canary=1; Path=\/; Max-Age=3600&quot;;\n    }\n\n    location \/ {\n        proxy_set_header Host $host;\n        proxy_set_header X-Real-IP $remote_addr;\n        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n        proxy_pass http:\/\/$backend_upstream;\n    }\n}\n<\/code><\/pre>\n<p>Cookie ile hedefli test, canary\u2019yi ilk olarak kendi g\u00f6zlerinle g\u00f6rmene yarar. \u00dc\u00e7 be\u015f ki\u015fiyle k\u0131sa bir tur at\u0131p nefes kontrol\u00fc yapt\u0131ktan sonra, trafi\u011fi yava\u015f yava\u015f a\u011f\u0131rl\u0131kla geri kalanlara a\u00e7aca\u011f\u0131z. Bu sayede ilk izlenimler taze taze elinde olur, gereksiz kahramanl\u0131k yapmadan ilerlersin.<\/p>\n<h3><span id=\"Agirlikli_trafik_Yuzde_hesaplariyla_degil_ayar_dugmesiyle\">A\u011f\u0131rl\u0131kl\u0131 trafik: Y\u00fczde hesaplar\u0131yla de\u011fil, ayar d\u00fc\u011fmesiyle<\/span><\/h3>\n<p>\u015eimdi weighted upstream\u2019i dahil ediyoruz. A\u011f\u0131rl\u0131klar\u0131 tek bir dosyada tutmak, s\u00fcr\u00fcm ad\u0131mlar\u0131nda i\u015fimizi kolayla\u015ft\u0131racak. K\u00fc\u00e7\u00fck bir script ile bu dosyay\u0131 g\u00fcncelleyece\u011fiz, ard\u0131ndan Nginx\u2019i hatas\u0131zca yeniden y\u00fckleyece\u011fiz. Map kullan\u0131m\u0131 da harika, \u00e7\u00fcnk\u00fc ko\u015fullu y\u00f6nlendirmeyi sadele\u015ftiriyor; merak edenler <a href=\"https:\/\/nginx.org\/en\/docs\/http\/ngx_http_map_module.html\" rel=\"nofollow noopener\" target=\"_blank\">map ile ko\u015fullu y\u00f6nlendirme<\/a> dok\u00fcman\u0131n\u0131 inceleyebilir.<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\"># \/etc\/nginx\/includes\/app_weights.conf\nupstream app_weighted {\n    server 127.0.0.1:8080 weight=10 max_fails=3 fail_timeout=10s;  # stable\n    server 127.0.0.1:9080 weight=0  max_fails=3 fail_timeout=10s;  # canary (ba\u015fta kapal\u0131)\n}\n<\/code><\/pre>\n<p>Bu tasar\u0131m\u0131n inceli\u011fi \u015fu: Canary a\u011f\u0131rl\u0131\u011f\u0131n\u0131 birden 0\u2019dan 5\u2019e, sonra 10\u2019a \u00e7ekebilirsin. B\u00f6ylece trafi\u011fi y\u00fczdelerle hesaplay\u0131p zihnini da\u011f\u0131tmadan, \u201cbiraz daha ver, biraz daha az\u201d hissiyle y\u00f6netirsin. D\u00fc\u011fmeyi \u00e7evirmek gibi. \u00dcstelik Nginx reload an\u0131nda ba\u011flant\u0131lar\u0131 kesmeden, zarif\u00e7e yeni ayarlarla devam eder. \u0130\u015fte o an i\u00e7inden bir \u201coh\u201d gelir, bilirsin ki g\u00fcvenle t\u0131rman\u0131yorsun.<\/p>\n<h2 id=\"section-4\"><span id=\"Saglik_kontrolu_Pasif_aktif_ve_loglarin_gozu\">Sa\u011fl\u0131k kontrol\u00fc: Pasif, aktif ve log\u2019lar\u0131n g\u00f6z\u00fc<\/span><\/h2>\n<p>Canary\u2019nin tad\u0131 sa\u011fl\u0131k kontrol\u00fcyle \u00e7\u0131kar. Nginx\u2019te pasif kontrol dedi\u011fimiz \u015fey, ba\u015far\u0131s\u0131z ba\u011flant\u0131lar\u0131 izlemesi, belirli say\u0131da hata sonras\u0131 sunucuyu k\u0131sa s\u00fcreli devre d\u0131\u015f\u0131 b\u0131rakmas\u0131d\u0131r. <strong>max_fails<\/strong> ve <strong>fail_timeout<\/strong> tam burada i\u015f g\u00f6r\u00fcyor. Ama bir de g\u00f6n\u00fcl rahatl\u0131\u011f\u0131 i\u00e7in aktif kontrol yapal\u0131m: Uygulama \/healthz gibi hafif bir endpoint ile \u201ciyiyim\u201d diyecek, biz de k\u00fc\u00e7\u00fck bir script ile buna bakaca\u011f\u0131z. Bir terslik g\u00f6r\u00fcrsek canary a\u011f\u0131rl\u0131\u011f\u0131n\u0131 an\u0131nda s\u0131f\u0131ra \u00e7ekip konuyu kapataca\u011f\u0131z.<\/p>\n<p>Log taraf\u0131n\u0131 da ihmal etmiyoruz. Canary iste\u011fini log\u2019larda etiketlemek, tek bak\u0131\u015fta \u201cbu hata canary\u2019den mi geldi?\u201d sorusunu cevaplaman\u0131 sa\u011flar. Kafan\u0131 kald\u0131r\u0131p ekran\u0131 s\u00fczmen yeter, rengini an\u0131nda veriyor.<\/p>\n<h3><span id=\"Uygulamanin_agzindan_iyiyim_demesi\">Uygulaman\u0131n a\u011fz\u0131ndan \u201ciyiyim\u201d demesi<\/span><\/h3>\n<p>Uygulaman\u0131n basit bir sa\u011fl\u0131k u\u00e7 noktas\u0131 olsun. Yan\u0131t\u0131 k\u00fc\u00e7\u00fck olsun, 200 d\u00f6ns\u00fcn, m\u00fcmk\u00fcnse s\u00fcr\u00fcm bilgisini de ta\u015f\u0131s\u0131n. Teknolojiden ba\u011f\u0131ms\u0131z gidelim, fikir net olsun yeter.<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\"># \u00d6rnek \/healthz yan\u0131t\u0131 (sade bir HTTP 200 ve k\u0131sa i\u00e7erik yeterli)\nHTTP\/1.1 200 OK\nContent-Type: text\/plain\n\nok version=1.2.3\n<\/code><\/pre>\n<p>Ard\u0131ndan ufak bir kontrol script\u2019i yazal\u0131m. Bu script belirli aral\u0131klarla \u00e7al\u0131\u015fabilir. Canary d\u00fc\u015ferse, a\u011f\u0131rl\u0131\u011f\u0131n\u0131 0 yapar, Nginx\u2019i test edip zarif\u00e7e yeniden y\u00fckler. Hata olursa otomatik geri al\u0131r. Bu k\u00fc\u00e7\u00fck g\u00fcvenlik kemeri gece uykunu tatl\u0131 yapar.<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\"># \/usr\/local\/bin\/canaryctl (\u00f6rnek)\n#!\/usr\/bin\/env bash\nset -euo pipefail\n\nWEIGHTS_FILE=&quot;\/etc\/nginx\/includes\/app_weights.conf&quot;\nSTABLE_W=${1:-10}   # stable a\u011f\u0131rl\u0131k\nCANARY_W=${2:-0}    # canary a\u011f\u0131rl\u0131k\n\nbackup=$(mktemp)\ncp &quot;$WEIGHTS_FILE&quot; &quot;$backup&quot;\n\ncat &gt; &quot;$WEIGHTS_FILE&quot; &lt;&lt;EOF\nupstream app_weighted {\n    server 127.0.0.1:8080 weight=${STABLE_W} max_fails=3 fail_timeout=10s;\n    server 127.0.0.1:9080 weight=${CANARY_W} max_fails=3 fail_timeout=10s;\n}\nEOF\n\nif nginx -t; then\n  systemctl reload nginx\n  echo &quot;[canaryctl] A\u011f\u0131rl\u0131klar g\u00fcncellendi: stable=${STABLE_W}, canary=${CANARY_W}&quot;\nelse\n  echo &quot;[canaryctl] Nginx test ba\u015far\u0131s\u0131z, geri al\u0131n\u0131yor&quot; &gt;&amp;2\n  mv &quot;$backup&quot; &quot;$WEIGHTS_FILE&quot;\n  exit 1\nfi\n<\/code><\/pre>\n<p>Bir de aktif kontrol\u00fc otomati\u011fe ba\u011flayan minik bir script yazal\u0131m. Canary iki denemenin ikisinde de yan\u0131t vermezse, a\u011f\u0131rl\u0131\u011f\u0131n\u0131 s\u0131f\u0131ra \u00e7eksin ve haber b\u0131raks\u0131n.<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\"># \/usr\/local\/bin\/canary-health-guard\n#!\/usr\/bin\/env bash\nset -euo pipefail\n\nCANARY_URL=&quot;http:\/\/127.0.0.1:9080\/healthz&quot;\nOK=0\nfor i in 1 2; do\n  if curl -fsS --max-time 2 &quot;$CANARY_URL&quot; | grep -qi &quot;ok&quot;; then\n    OK=$((OK+1))\n  fi\n  sleep 1\ndone\n\nif [ &quot;$OK&quot; -lt 2 ]; then\n  echo &quot;[guard] Canary sa\u011fl\u0131ks\u0131z g\u00f6r\u00fcn\u00fcyor, a\u011f\u0131rl\u0131k s\u0131f\u0131rlan\u0131yor&quot; &gt;&amp;2\n  \/usr\/local\/bin\/canaryctl 10 0 || true\nfi\n<\/code><\/pre>\n<p>Bu guard\u2019\u0131 bir sistem zamanlay\u0131c\u0131s\u0131yla d\u00fczenli aral\u0131klarla ko\u015fturabilirsin. Hafif, anla\u015f\u0131l\u0131r ve tek i\u015fini yap\u0131yor. G\u00fcn\u00fcn sonunda arad\u0131\u011f\u0131m\u0131z da bu asl\u0131nda.<\/p>\n<h3><span id=\"Loglarda_canaryyi_boyamak\">Log\u2019larda canary\u2019yi boyamak<\/span><\/h3>\n<p>Log format\u0131na ufak bir etiket ekleyelim. B\u00f6ylece canary kaynakl\u0131 istekleri bir bak\u0131\u015fta ay\u0131rt eder, sorun oldu\u011funda nereden geldi\u011fini h\u0131zl\u0131ca g\u00f6r\u00fcrs\u00fcn.<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\"># \/etc\/nginx\/nginx.conf\nmap $upstream_pool $canary_tag {\n    canary   &quot;canary&quot;;\n    default  &quot;stable&quot;;\n}\n\nlog_format canary '$remote_addr - - [$time_local] &quot;$request&quot; $status $body_bytes_sent '\n                  '&quot;$http_referer&quot; &quot;$http_user_agent&quot; pool=$canary_tag rt=$request_time';\n\naccess_log \/var\/log\/nginx\/access_canary.log canary;\n<\/code><\/pre>\n<p>Log\u2019lara bakmay\u0131 g\u00fcnl\u00fck ritmine almak iyi bir al\u0131\u015fkanl\u0131k. Birka\u00e7 dakikal\u0131k bak\u0131\u015f, saatlerce s\u00fcrecek bir ar\u0131zay\u0131 ba\u015flamadan bitirebilir. K\u00fc\u00e7\u00fck notlar, b\u00fcy\u00fck rahatl\u0131klar.<\/p>\n<h2 id=\"section-5\"><span id=\"Guvenli_rollback_Geri_donus_yolunu_bastan_cizmek\">G\u00fcvenli rollback: Geri d\u00f6n\u00fc\u015f yolunu ba\u015ftan \u00e7izmek<\/span><\/h2>\n<p>Rollback i\u015fi, kriz an\u0131nda al\u0131nan h\u0131zl\u0131 bir karar gibi g\u00f6r\u00fcn\u00fcr ama as\u0131l sihri \u00f6nceden yap\u0131lan haz\u0131rl\u0131ktad\u0131r. Dosya d\u00fczenini iki s\u00fcr\u00fcm\u00fc ayn\u0131 anda tutacak \u015fekilde kurars\u0131n; current diye bir sembolik ba\u011flant\u0131 olur, stable oraya bakar, canary ise yeni s\u00fcr\u00fcme. Sorun \u00e7\u0131karsa current\u2019\u0131 eskiye \u00e7evirir, Nginx\u2019i zarif\u00e7e reload edersin. \u0130\u015flem biter, kullan\u0131c\u0131 anlamaz bile.<\/p>\n<p>Nginx taraf\u0131nda da geri d\u00f6n\u00fc\u015f plan\u0131n haz\u0131r: Canary a\u011f\u0131rl\u0131\u011f\u0131n\u0131 0 yap, stable\u2019\u0131 yukar\u0131 \u00e7ek. Reload \u00f6ncesi her zaman test et, test hatal\u0131ysa otomatik geri al. Bu kural\u0131 cebine koyarsan, \u201creload korkusu\u201d hayat\u0131ndan sessizce \u00e7\u0131kar. \u0130nce bir ayr\u0131nt\u0131 gibi ama gece 02:00\u2019de alt\u0131n de\u011ferinde.<\/p>\n<p>Tek tu\u015fla d\u00f6n\u00fc\u015f i\u00e7in bir komut al\u0131\u015fkanl\u0131\u011f\u0131 geli\u015ftirmek iyi oluyor. Mesela canaryctl ile a\u011f\u0131rl\u0131klar\u0131 y\u00f6netiyorsun; ayn\u0131 ara\u00e7 hatada saniyeler i\u00e7inde geri alabiliyor. Bir ko\u015fu band\u0131nda h\u0131z\u0131n\u0131 bir t\u0131k d\u00fc\u015f\u00fcrmek gibi, ritim bozulmadan devam ediyorsun.<\/p>\n<h3><span id=\"Tek_komutla_guvenlik_canaryctl_ramp-up_ve_rollback\">Tek komutla g\u00fcvenlik: canaryctl ramp-up ve rollback<\/span><\/h3>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\"># Canary'yi %10'a denk gelecek \u015fekilde art\u0131r (\u00f6rnek: 9\/1 ya da 10\/1 gibi)\n\/usr\/local\/bin\/canaryctl 9 1\n\n# %30'a do\u011fru yumu\u015fak bir art\u0131\u015f\n\/usr\/local\/bin\/canaryctl 7 3\n\n# Bir \u015feyler ters gidiyor, hemen geri d\u00f6n\n\/usr\/local\/bin\/canaryctl 10 0\n<\/code><\/pre>\n<p>Burada y\u00fczdeye k\u00f6r\u00fc k\u00f6r\u00fcne tak\u0131lma, genel trafik yo\u011funlu\u011funu ve uygulaman\u0131n do\u011fas\u0131n\u0131 bilerek artt\u0131r. Kimisi 5\u2019er 5\u2019er gider, kimisi 10-10 atlar. \u00d6nemli olan, her art\u0131\u015f\u0131n ard\u0131ndan nefes kontrol\u00fc yapman ve log\u2019lara \u015f\u00f6yle bir g\u00f6z atman. Bazen bir sat\u0131r log, bir saatin kaderini de\u011fi\u015ftirir.<\/p>\n<h2 id=\"section-6\"><span id=\"Aksam_plani_Kucuk_bir_surumu_canary_ile_yayina_alma\">Ak\u015fam plan\u0131: K\u00fc\u00e7\u00fck bir s\u00fcr\u00fcm\u00fc canary ile yay\u0131na alma<\/span><\/h2>\n<p>Ak\u015fam \u00fcst\u00fc sessizlik \u00e7\u00f6km\u00fc\u015f, kahveni tazeledin ve mini bir s\u00fcr\u00fcm bekliyor. \u00d6nce ekipten iki \u00fc\u00e7 ki\u015fiye cookie veriyorsun. Taray\u0131c\u0131lar\u0131na ?canary=1 ile bir tur att\u0131r, sayfalar\u0131n a\u00e7\u0131l\u0131\u015f\u0131nda tuhafl\u0131k var m\u0131 bak. Bu arada \/healthz tertemiz, g\u00f6z\u00fcn ayd\u0131n. Nginx log\u2019lar\u0131nda canary etiketiyle gelen istekleri izlerken, ufak tefek uyar\u0131lar g\u00f6rebilirsin; yeni bir endpoint biraz a\u011f\u0131r kalm\u0131\u015f mesela, notunu al.<\/p>\n<p>Sonra a\u011f\u0131rl\u0131klar\u0131 9\/1 yap\u0131p bir on dakika bak\u0131yorsun. Error rate k\u0131p\u0131rdand\u0131 m\u0131? H\u0131zlarda g\u00f6zle g\u00f6r\u00fcl\u00fcr bir d\u00fc\u015f\u00fc\u015f var m\u0131? Yoksa 7\/3\u2019e y\u00fckseltiyorsun. Ad\u0131mlar aras\u0131nda uygulaman\u0131n nefesini \u00f6l\u00e7, gereksiz h\u0131zla kapt\u0131r\u0131p gitme. Trafi\u011fin ritmini dinle, log\u2019lar\u0131n \u015fark\u0131s\u0131n\u0131 duy. Bir yerde t\u0131n\u0131 bozulursa, canary\u2019i an\u0131nda 0\u2019a \u00e7ekip nefeslendir, gerekirse hata ay\u0131klamaya geri d\u00f6n.<\/p>\n<p>Bu s\u0131rada uygulama g\u00fcncellemesi dil seviyesinde bir de\u011fi\u015fiklik i\u00e7eriyorsa, \u00f6rne\u011fin bir PHP maj\u00f6r g\u00fcncellemesi gibi, geriye uyumlulu\u011fu \u00f6nceden tatl\u0131 tatl\u0131 kontrol etmek iyi fikir. B\u00f6yle durumlarda, <a href=\"https:\/\/www.dchost.com\/blog\/php-8-x-yukseltme-kontrol-listesi-wordpress-ve-laravelde-geriye-uyumluluk-opcache-preload-ve-fpm-havuz-ayarlari-nasil-tatli-tatli-kurulur\/\">PHP 8.x y\u00fckseltme kontrol listesinde pratik uyumluluk notlar\u0131<\/a> gibi bir yol haritas\u0131n\u0131 elinin alt\u0131nda tutmak, canary\u2019nin y\u00fck\u00fcn\u00fc de azalt\u0131r. \u00c7\u00fcnk\u00fc bilirsin, baz\u0131 sorunlar canl\u0131da de\u011fil, mutfakta \u00e7\u00f6z\u00fcld\u00fc\u011f\u00fcnde en tatl\u0131s\u0131d\u0131r.<\/p>\n<p>Her \u015fey yolundaysa final turu geliyor. A\u011f\u0131rl\u0131klar\u0131 5\/5\u2019e getirip biraz daha izliyorsun, sonra yava\u015f yava\u015f 3\/7, 2\/8, 1\/9 derken bir bakm\u0131\u015fs\u0131n stable art\u0131k neredeyse bo\u015fa d\u00fc\u015fm\u00fc\u015f. Bu noktada current ba\u011flant\u0131n\u0131 yeni s\u00fcr\u00fcme al\u0131yor, stable\u2019\u0131 yedek gibi tutmaya devam ediyorsun. Bir s\u00fcre daha g\u00f6zlem yap, sonra eski s\u00fcr\u00fcm\u00fc raflara kald\u0131r. K\u00fc\u00e7\u00fck zaferlerin tad\u0131n\u0131 \u00e7\u0131kar, b\u00fcy\u00fck f\u0131rt\u0131nalara gerek yok.<\/p>\n<h2 id=\"section-7\"><span id=\"Ek_notlar_TLS_reload_ve_kucuk_tehlikeler\">Ek notlar: TLS, reload ve k\u00fc\u00e7\u00fck tehlikeler<\/span><\/h2>\n<p>Canary\u2019nin teknik ritminde iki k\u00fc\u00e7\u00fck detay hayat kurtar\u0131r. Birincisi, Nginx reload\u2019un zarafeti; her zaman \u00f6nce test et, sonra reload. Bu rutini ezberlersen, \u201cya d\u00fckkan\u0131 kapat\u0131rsam\u201d endi\u015fesi \u00e7ekip gider. <a href=\"https:\/\/nginx.org\/en\/docs\/control.html\" rel=\"nofollow noopener\" target=\"_blank\">nginx -t ve zarif reload<\/a> \u00fczerine k\u0131sa bir okuma bile bak\u0131\u015f a\u00e7\u0131n\u0131 berrakla\u015ft\u0131r\u0131r. \u0130kincisi, sertifika yenilemeleri. ACME otomasyonu ile sertifikalar taze kal\u0131r, reload ayn\u0131 zarafetle s\u00fcrer; bu sayede canary ak\u0131\u015f\u0131n\u0131 kesmeden g\u00fcvenli\u011fi de canl\u0131 tutars\u0131n.<\/p>\n<p>Bazen canary ba\u015far\u0131s\u0131z oldu\u011funda pani\u011fe kap\u0131lmak kolayd\u0131r. Oysa plan basit: A\u011f\u0131rl\u0131\u011f\u0131 s\u0131f\u0131rla, log\u2019tan ipucunu topla, k\u00fc\u00e7\u00fck bir d\u00fczeltme yap, tekrar k\u00fc\u00e7\u00fck bir payla dene. Bu \u00e7evrim, duvarlara \u00e7arpmadan ilerleme sanat\u0131d\u0131r. Her tur seni g\u00fc\u00e7lendirir, her tur sistemi tan\u0131t\u0131r. Yeter ki acele etme, izlemeyi b\u0131rakma, k\u00fc\u00e7\u00fck ad\u0131mlar\u0131n k\u0131ymetini bil.<\/p>\n<h2 id=\"section-8\"><span id=\"Kapanis_Canary_kucuk_cesur_adimlarin_guvenligi\">Kapan\u0131\u015f: Canary, k\u00fc\u00e7\u00fck cesur ad\u0131mlar\u0131n g\u00fcvenli\u011fi<\/span><\/h2>\n<p>Bir uygulamay\u0131 b\u00fcy\u00fctmenin yolu, ona sab\u0131rla e\u015flik etmekten ge\u00e7iyor. Canary da\u011f\u0131t\u0131m\u0131 bu sabr\u0131n pratik hali; yeni olan\u0131 ufak ufak sahneye \u00e7\u0131kar\u0131yor, g\u00f6zlerinle tart\u0131yor, sonra alk\u0131\u015f\u0131 veriyorsun. Nginx ile a\u011f\u0131rl\u0131kl\u0131 y\u00f6nlendirme bu ak\u0131\u015f\u0131 parmaklar\u0131n\u0131n ucuna getiriyor; k\u00fc\u00e7\u00fck bir script, basit bir sa\u011fl\u0131k kontrol\u00fc ve nazik bir reload ile i\u015fin kontrol\u00fcn\u00fc tamamen eline al\u0131yorsun. \u00dcstelik her \u015fey o kadar do\u011fal ak\u0131yor ki, bir yerden sonra \u201cba\u015fka t\u00fcrl\u00fcs\u00fc nas\u0131l olurdu ki\u201d demeye ba\u015fl\u0131yorsun.<\/p>\n<p>Kapan\u0131\u015f\u0131 birka\u00e7 pratik notla yapal\u0131m: Canary\u2019yi \u00f6nce kendin tat, ekibe tatt\u0131r, sonra yava\u015f yava\u015f herkese a\u00e7. Log\u2019lara kulak ver, sa\u011fl\u0131k kontrollerini hafif ama g\u00fcvenilir tut. Rollback yolun her zaman a\u00e7\u0131k kals\u0131n, test etmeden reload etme. Ve l\u00fctfen, g\u00fczel giden bir ak\u015fam\u0131 gereksiz risklerle bozma. Umar\u0131m burada payla\u015ft\u0131klar\u0131m, bir sonraki k\u00fc\u00e7\u00fck s\u00fcr\u00fcm\u00fcn\u00fc huzurla yay\u0131na almanda sana yol olur. Bir dahaki yaz\u0131da g\u00f6r\u00fc\u015fmek \u00fczere, \u015fimdilik al\u00e7akg\u00f6n\u00fcll\u00fc canary\u2019lere selam olsun.<\/p>\n<hr \/>\n<p>Ek kaynak: Nginx upstream ve a\u011f\u0131rl\u0131klar i\u00e7in <a href=\"https:\/\/nginx.org\/en\/docs\/http\/ngx_http_upstream_module.html\" rel=\"nofollow noopener\" target=\"_blank\">resmi dok\u00fcman<\/a>, ko\u015fullu y\u00f6nlendirme i\u00e7in <a href=\"https:\/\/nginx.org\/en\/docs\/http\/ngx_http_map_module.html\" rel=\"nofollow noopener\" target=\"_blank\">map mod\u00fcl\u00fc<\/a>, g\u00fcvenli yeniden y\u00fckleme i\u00e7in <a href=\"https:\/\/nginx.org\/en\/docs\/control.html\" rel=\"nofollow noopener\" target=\"_blank\">kontrol komutlar\u0131<\/a>.<\/p>\n<\/div>","protected":false},"excerpt":{"rendered":"<p>\u0130&ccedil;indekiler1 Giri\u015f: K\u00fc\u00e7\u00fck bir s\u00fcr\u00fcm, b\u00fcy\u00fck bir nefes2 Canary da\u011f\u0131t\u0131m\u0131 tam olarak ne? Neden VPS\u2019te i\u015fleri kolayla\u015ft\u0131r\u0131r?3 Nginx ile a\u011f\u0131rl\u0131kl\u0131 y\u00f6nlendirme nas\u0131l kurulur?3.1 Hedefli test: Cookie ile sadece sen ve ekibin g\u00f6rs\u00fcn3.2 A\u011f\u0131rl\u0131kl\u0131 trafik: Y\u00fczde hesaplar\u0131yla de\u011fil, ayar d\u00fc\u011fmesiyle4 Sa\u011fl\u0131k kontrol\u00fc: Pasif, aktif ve log\u2019lar\u0131n g\u00f6z\u00fc4.1 Uygulaman\u0131n a\u011fz\u0131ndan \u201ciyiyim\u201d demesi4.2 Log\u2019larda canary\u2019yi boyamak5 G\u00fcvenli rollback: [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":1984,"comment_status":"","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[26],"tags":[],"class_list":["post-1983","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\/1983","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=1983"}],"version-history":[{"count":0,"href":"https:\/\/www.dchost.com\/blog\/wp-json\/wp\/v2\/posts\/1983\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.dchost.com\/blog\/wp-json\/wp\/v2\/media\/1984"}],"wp:attachment":[{"href":"https:\/\/www.dchost.com\/blog\/wp-json\/wp\/v2\/media?parent=1983"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.dchost.com\/blog\/wp-json\/wp\/v2\/categories?post=1983"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.dchost.com\/blog\/wp-json\/wp\/v2\/tags?post=1983"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}