<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های فرهاد صادقی</title>
        <link>https://virgool.io/feed/@farhad.sadeghi</link>
        <description>مهندس نرم افزار، طراحی و راه اندازی سیستم های نرم افزاری بر پایه معماری میکروسرویس</description>
        <language>fa</language>
        <pubDate>2026-04-14 08:52:17</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/121988/avatar/67MbOq.jpg?height=120&amp;width=120</url>
            <title>فرهاد صادقی</title>
            <link>https://virgool.io/@farhad.sadeghi</link>
        </image>

                    <item>
                <title>Anti-Corruption Layer (ACL) / Adapter</title>
                <link>https://virgool.io/@farhad.sadeghi/anti-corruption-layer-acl-adapter-wrkinyp6cxwr</link>
                <description>فرض کنید ما در کسب و کار خودمان یا در سازمانی که کار می کنیم از معماری میکروسرویس و REST API استفاده می کنیم. ما یک سری سرویس را به صورت soap از شرکت ها یا واحدهای دیگر دریافت می کنیم.حال سوال اینجاست که بهترین و اصولی ترین جایی که این تبدیل پروتکل باید انجام بشه کجاست؟ آیا داخل هر سرویسی که نیاز به فراخوانی سرویس soap دارد باید این کار انجام شود، داخل Api Gateway باید این تبدیل انجام شود یا جایی دیگر؟توی این مطلب میخوام این موضوع را به صورت خیلی ساده و خودمونی و برای همیشه روشن کنم. قبل از اینکه SOAP با REST قاطی بشه و سیستم ها تبدیل به آش شله قلمکار بشن.جواب کوتاه و محکمبهترین و اصولی‌ترین جا برای تبدیل SOAP → REST یک لایهٔ Anti-Corruption / Adapter / Integration Layer مستقل بیرون از سرویس‌های میکروسرویسی است.جواب کامل و مهندسیدر معماری میکروسرویس، هیچ‌وقت سرویس‌هات رو وادار نکن با دنیای عجیب SOAP صحبت کنن.سرویس‌های تو باید فقط REST بلد باشن و فاز «من هم SOAP بلدم، هم REST، هم GraphQL، هم چایی دم می‌کنم» نگیرن.پس باید چی کار کنیم؟بهترین محل تبدیل پروتکل کجاست؟1. لایه‌ی Anti-Corruption Layer (ACL) / Adapterاین همون لایه‌ایه که مثل مترجم همزمان سازمان ملل بین سرویس‌های مدرن RESTای تو و سرویس‌های باستانی SOAP طرف مقابل می‌ایسته.این لایه:درخواست REST داخلی رو می‌گیرهتبدیلش می‌کنه به SOAPبا سرویس بیرونی حرف می‌زنهجواب SOAP رو تبدیل می‌کنه به JSON/RESTو در نهایت «تمیز و اتو کشیده» تحویل میکروسرویس‌ها می‌دهچرا اینجا بهترین گزینه‌ست؟جداسازی کامل پروتکل خارجی از معماری داخلیسرویس‌های داخلی پاک و ساده می‌مونند (Single Responsibility)اگر فردا SOAP منقرض شد یا REST بیرونی به gRPC تغییر کرد… فقط همین لایه رو آپدیت می‌کنیامکان کشینگ، لاگینگ، ریت‌لیمیتینگ، امنیت و حتی Retry logic اینجا خیلی راحت‌ترهدیباگ و مانیتورینگ centralized می‌شه2. گزینه‌های غلط که گاهی وسوسه‌انگیز می‌شنانجام تبدیل داخل خود میکروسرویس‌هاسرویس‌هات چاق و شلخته می‌شن، وابسته به SOAP می‌شن و SRP میره رو هوا.گیت‌وی، APIگیت‌وی باید Routing و Security و throttling بکنه… تبدیل SOAP به REST؟عزیزم نه! اون طفل معصوم تحمل این مصیبت رو نداره.ساختار توصیه‌شدهInternal microservices (REST)⬇️⬆️Integration Layer / SOAP Adapter / ACL⬇️⬆️External SOAP Servicesارتباط ACL با گیت وی چطور باید باشه؟اول از همه: چه کسی با چه کسی حرف می‌زند؟در معماری درست، جریان ارتباط این‌جوریه:Client⬇️API Gateway⬇️Microservice (REST)⬇️Anti-Corruption Layer (ACL)⬇️External SOAP serviceیعنی ACL زیرمجموعهٔ Backend است نه زیرمجموعهٔ Gateway.چرا این ترتیب درسته؟1. API Gateway وظیفه‌اش این‌هاست:احراز هویت/مجوزRate LimitingRoutingامنیتلاگ و مانیتورینگ سطح بالاaggregation خیلی سادهگیت‌وی نباید تبدیل پروتکل انجام بده.چون اگه گیت‌وی SOAP-دان بشه، دیگه بهش نمی‌گن Gateway… می‌گن «فرودگاه خدمات متفرقه!» 😅2. ACL یک سرویس backend است، نه یک سرویس لبه (edge)وظیفه‌اش:ترجمه REST → SOAPترجمه SOAP → RESTهندل کردن Retry، Error mapping، Fault mappingکشینگ خاص سرویس خارجیلاگ‌های سطح پروتکل خارجیاین کارها اساساً کار سرویس‌های داخلی است، نه Gateway.معماری درست و تمیز (که از دور هم داد می‌زند: من حرفه‌ای‌ام)Flow سطح کاربردیکلاینت به گیت‌وی ضربه می‌زندگیت‌وی درخواست را به میکروسرویس تو پاس می‌دهدسرویس تو اگر نیاز داشت با سرویس خارجی حرف بزند، به ACL می‌گویدACL می‌رود SOAP را صدا می‌زندپاسخ را تمیز می‌کند و REST برمی‌گرداندسرویس تو جواب نهایی را می‌دهدگیت‌وی آن را تحویل کلاینت می‌دهدیک سؤال مهم:«حالا گیت‌وی باید ACL را ببیند یا نه؟»جواب:نه. به هیچ‌وجه!ACL یک سرویس داخلی است.گیت‌وی فقط باید سرویس‌های Domain را ببیند، نه Adapterهای پشت صحنه را.اگر گیت‌وی ACL را ببیند:لایهٔ دامنه دور زده می‌شودcoupling بالا می‌رودACL مجبور می‌شود رفتار API کاربر را تامین کند!! که فاجعه است.معماری layered رسماً می‌کشد میرودپس معماری درست چیه؟Gateway فقط به میکروسرویس‌ها روت می‌کندمیکروسرویس‌ها با ACL حرف می‌زنندACL با SOAP حرف می‌زندیک تشبیه بامزه:گیت‌وی مثل گارد ورودی یک شرکت است.کارمندها (میکروسرویس‌ها) داخل ساختمان هستند.ACL مثل مترجم شرکت است.آیا گارد ورودی باید با مترجم وارد بحث شود؟نه!فقط با کارمندها حرف می‌زند.کارمندها اگر نیاز داشتند، می‌روند سراغ مترجم. 😄میمونه بحث احراز هویت و امنیت:احتمالا سرویس soap نیاز به احراز هویت دارد، نام کاربری و رمز عبور اون توی چه لایه ای باید قرار بگیره؟این سؤال دقیقاً همون نقطه‌ایه که خیلی از تیم‌ها اشتباه می‌کنن و آخرش پسورد SOAP رو میذارن تو گیت‌وی، بعد گیت‌وی دپرس میشه و شب‌ها کابوس WSDL می‌بینه 😄روش شسته‌رفته و معماری‌شده:نام کاربری و رمز سرویس SOAP باید در خودِ لایهٔ ACL ذخیره و استفاده شود.نه در گیت‌وی،نه در میکروسرویس‌های داخلی،نه در کلاینت.فقط و فقط ACL.چرا باید credentialهای SOAP در ACL باشند؟1. ACL تنها لایه‌ای است که مستقیماً با SOAP سرویس خارجی حرف می‌زندپس طبیعیه که احراز هویت مخصوص SOAP هم همین‌جا انجام بشه.میکروسرویس‌های داخلی نباید حتی بوی SOAP بهشون بخوره.2. جداسازی مسئولیت‌ها (SRP)گیت‌وی = احراز هویت کاربران سیستم شمامیکروسرویس = منطق دامنهACL = ترجمه پروتکل + امنیت سرویس‌های خارجیاگر پسورد SOAP رو جای دیگه بذاری، این مرزهای طلایی قاطی میشه.3. امنیتاگر credentialهای SOAP وارد گیت‌وی شوند:گیت‌وی عملاً تبدیل می‌شود به سرویس خارجی شماattack surface بیشتر می‌شودمدیریت Rotation سخت می‌شودلاگ‌ها خطرناک می‌شونداما اگر فقط ACL آنها را بداند،امنیت و مدیریت ساده و متمرکز می‌ماند.بهترین مکان ذخیره credentials دقیقا کجاست؟داخل ACL، ولی در این ساختار:ذخیره در Secret Manager (مثل Vault, AWS Secrets Manager, Kubernetes Secrets)Inject شدن در ACL هنگام startupاستفاده فقط در کد adapterعدم ذخیره سازی مستقیم در config معمولی یا imageچه چیزی هرگز نباید اتفاق بیفتد؟گیت‌وی credential SOAP را پاس بدهدکلاینت credential SOAP را بدانددرخواست REST داخلی شامل یوزر/پسورد SOAP باشدسرویس داخلی خودش credential را ذخیره کندپیشنهاد بهتر: Token Relay + Rotationاگر سرویس SOAP امکان استفاده از token داشته باشد (بعضی WSDLها دارند)،بهترین کار:ACL در startup یا دوره‌ای token بگیردtoken را در حافظه یا cache امن نگه داردبرای هر درخواست از همان token استفاده کنداین کار امنیت را چند برابر بالا می‌برد.</description>
                <category>فرهاد صادقی</category>
                <author>فرهاد صادقی</author>
                <pubDate>Sun, 12 Apr 2026 17:07:26 +0330</pubDate>
            </item>
                    <item>
                <title>آموزش Kubernetes - قسمت چهارم</title>
                <link>https://virgool.io/@farhad.sadeghi/%D8%A2%D9%85%D9%88%D8%B2%D8%B4-kubernetes-%D9%82%D8%B3%D9%85%D8%AA-%DA%86%D9%87%D8%A7%D8%B1%D9%85-qavxanba1hpc</link>
                <description>راه اندازی کلاستر Kubernetesدر قسمت قبل آموزش کوبرنتیز، مراحل نصب kubectl، kubelet و kubeadm بصورت کامل شرح داده شد و روی همه نودهای کلاستر مراحل نصب انجام شد.برای راه اندازی کلاستر کوبرنتیز تنها نصب نرم افزارها روی نودها کفایت نمی کند. در این مرحله باید master node راه اندازی (init) شود و worker node ها یکی یکی به آن متصل شوند.به مجموعه کارهایی که در این قسمت انجام خواهیم داد، اصطلاحا بوت استرپ کردن کلاستر کوبرنتیز (Kubernetes cluster bootstrapping) می گویند.1. Pre-operation checkssystemctl status containerd
systemctl status kubeletقبل از bootstrap کردن کلاستر کوبرنتیز با اجرای دستورات بالا به ترتیب وضعیت containerd و kubelet را بررسی می کنیم.containerd باید enabled و active(running) باشد.kubelet باید enabled باشد ولی active نخواهد بود. kubelet بعد از kubeadm init اجرا خواهد شد.On most modern Linux systems that use systemd (like Ubuntu, CentOS, Debian, RHEL), there are several possible service states.When you run:systemctl status &lt;service-name&gt;You’ll mainly see two types of states:1️⃣ Active State (Primary Service State)These are the most common:active (running) → Service is running properlyactive (exited) → Ran successfully and exited (normal for one-shot services)inactive (dead) → Not runningfailed → Service crashed or failed to startactivating → In the process of startingdeactivating → In the process of stoppingSo there are 6 common active states.2️⃣ Enablement State (Boot Status)Check with:systemctl is-enabled &lt;service-name&gt;Possible results:enabled → Starts at bootdisabled → Does not start at bootstatic → Cannot be enabled manually (dependency only)masked → Completely blocked from startingindirect → Enabled via another servicegenerated → Created dynamicallytransient → Temporary unitSo around 7 enablement states.✅ Enable a servicesudo systemctl enable &lt;service-name&gt;

#Example (kubelet):
sudo systemctl enable kubelet▶️ Start it immediately (optional)Enabling does not start it right away.To start it now:sudo systemctl start &lt;service-name&gt;Or both at once:sudo systemctl enable --now &lt;service-name&gt;Example:sudo systemctl enable --now kubeletسایر مواردی که باید چک شوند وضعیت SELinux و firewalld می باشند. SELinux باید Permissive باشد و firewalld باید inactive باشد.getenforce
systemctl status firewalld2. Kubeadm initبرای راه اندازی و bootstrap کردن کلاستر کوبر از دستور kubeadm init استفاده می کنیم.kubeadm init --apiserver-advertise-address=192.168.65.43 --pod-network-cidr=10.96.0.0/12 –-kubernetes-version=1.34.4ممکن است Master Node ما دارای چند کارت شبکه باشد (این امر در بحث کلاستر کوبرنیتز و نودهای مستر مرسوم است)، در این صورت باید یکی از آنها را با وارد کردن IP در پارامتر apiserver-advertise-address مشخص کنیم. با این کار، Kubeapi روی همان IP هاست می شود.ممکن است نودهای ما در ساب شبکه های مختلف قرار داشته باشند. در پارامتر pod-network-cidr باید رنج IP نودها را مشخص کنیم.اگر نسخه Kubernetes را مشخص نکنیم، آخرین نسخه نصب می شود.توجه: در محیط محصول همه imageها روی یک nexuse قرار می گیرند و کوبرنتیز از روی آن، image ها را لود می کند و imageها بصورت دستی نباید کپی شوند.وقتی کامند kubeadm init اجرا می شود کارها/فازهای زیر انجام می شود:preflight                     Run pre-flight checks
certs                         Certificate generation
  /ca                           Generate the self-signed Kubernetes CA to provision identities for other Kubernetes components
  /apiserver                    Generate the certificate for serving the Kubernetes API
  /apiserver-kubelet-client     Generate the certificate for the API server to connect to kubelet
  /front-proxy-ca               Generate the self-signed CA to provision identities for front proxy
  /front-proxy-client           Generate the certificate for the front proxy client
  /etcd-ca                      Generate the self-signed CA to provision identities for etcd
  /etcd-server                  Generate the certificate for serving etcd
  /etcd-peer                    Generate the certificate for etcd nodes to communicate with each other
  /etcd-healthcheck-client      Generate the certificate for liveness probes to healthcheck etcd
  /apiserver-etcd-client        Generate the certificate the apiserver uses to access etcd
  /sa                           Generate a private key for signing service account tokens along with its public key
kubeconfig                    Generate all kubeconfig files necessary to establish the control plane and the admin kubeconfig file
  /admin                        Generate a kubeconfig file for the admin to use and for kubeadm itself
  /super-admin                  Generate a kubeconfig file for the super-admin
  /kubelet                      Generate a kubeconfig file for the kubelet to use *only* for cluster bootstrapping purposes
  /controller-manager           Generate a kubeconfig file for the controller manager to use
  /scheduler                    Generate a kubeconfig file for the scheduler to use
etcd                          Generate static Pod manifest file for local etcd
  /local                        Generate the static Pod manifest file for a local, single-node local etcd instance
control-plane                 Generate all static Pod manifest files necessary to establish the control plane
  /apiserver                    Generates the kube-apiserver static Pod manifest
  /controller-manager           Generates the kube-controller-manager static Pod manifest
  /scheduler                    Generates the kube-scheduler static Pod manifest
kubelet-start                 Write kubelet settings and (re)start the kubelet
wait-control-plane            Wait for the control plane to start
upload-config                 Upload the kubeadm and kubelet configuration to a ConfigMap
  /kubeadm                      Upload the kubeadm ClusterConfiguration to a ConfigMap
  /kubelet                      Upload the kubelet component config to a ConfigMap
upload-certs                  Upload certificates to kubeadm-certs
mark-control-plane            Mark a node as a control-plane
bootstrap-token               Generates bootstrap tokens used to join a node to a cluster
kubelet-finalize              Updates settings relevant to the kubelet after TLS bootstrap
  /enable-client-cert-rotation  Enable kubelet client certificate rotation
addon                         Install required addons for passing conformance tests
  /coredns                      Install the CoreDNS addon to a Kubernetes cluster
  /kube-proxy                   Install the kube-proxy addon to a Kubernetes cluster
show-join-command             Show the join command for control-plane and worker nodePreflight: همه پیش نیازها چک می شود.Certs: کار Certificate generation انجام می شود. در این مرحله کوبرنتیز برای خودش یک CA بالا می آورد و هرچقدر که certificate نیاز داشته باشد از CA دریافت می کند. در کلاستر کوبرنتیز همه ارتباطات بین اجزای کلاستر از جمله ارتباط بین kubectl و kubeapi و سایر ارتباطات داخل کلاستر بر پایه certificate انجام می شود یعنی علاوه بر اینکه ارتباط بین اجزا encrypt می شود، Authentication هم با certificate انجام می شود.kubeconfig: فایلهای کانفیگ ایجاد می شود.به عنوان مثال تا ایجای کار kubelet در حالت اجرا نبود و قابلیت اجرا شدن نداشت چون فایل کانفیگی برای آن وجود نداشت. در این مرحله kubelet کانفیگ می شود و آماده اجراست.etcd: در این مرحله static Pod مربوط به etcd کانفیگ می شود.static pod ها، همه پادهایی هستند که برای بوت استرپ کردن و اجرای کلاستر کوبرنتیز نیاز می باشند مانند kubeapi, kubelet, etcd و ... . همانطور که قبلا هم گفته شد، کلاستر کوبرنتیز خود یک میکروسرویس می باشد که همه قسمت های آن در قالب Pod اجرا می شود.control-plane: در این مرحله static Pod های kube-apiserver, kube-controller-manager و kube-scheduler کانفیگ می شوند.kubelet-start: تنظیمات kubelet اعمال شده و start/restart می شود.wait-control-plane: منتظر می ماند تا control plane اجرا شده و stable شود.upload-config: در این مرحله کانفیگ kubeadm و kubelet روی ConfigMap بارگذاری می شود.در کلاستر کوبرنتیز، Pod ها readonly هستند و در طول اجرا ویرایش نمی شوند. بعنوان مثال اگر یک پاد از connection string برای اتصال به پایگاه داده استفاده می کند ما نمی توانیم پاد را ویرایش کنیم و connection string آن را تغییر دهیم و به پایگاه داده جدید متصل کنیم. برای این منظور همه کانفیگ های مورد نیاز Pod ها در فایل ConfigMap نوشته می شوند. و در صورت نیاز، این فایل ConfigMap می باشد که تغییر می کند.upload-certs: همه certificate های kubeadm بارگذاری می شوند.mark-control-plane: نود فعلی بعنوان نود مستر (Control-Plane) تگ گذاری می شود.bootstrap-token: توکن کلاستر کوبرنتیز ایجاد می شود. این توکن برای اتصال سایر نودها به کلاستر کوبرنتیز استفاده می شود.kubelet-finalize: در این مرحله kubelet نهایی می شود.addon: در این مرحله addon های دیگر مانند coredns و kube-proxy نصب می شوند.show-join-command: در مرحله آخر، join-command نمایش داده می شود. cluster token هم داخل این کامند وجود دارد. سایر نودها برای اتصال به کلاستر، تنها کافی است که join-command را اجرا کنند.#How to export/import images into containerd
--------------------------------------
crictl images ls
ctr -n k8s.io images import k8s-v1.35-all.tar
ctr -n k8s.io images export scheduler.tar registry.k8s.io/kube-scheduler:v1.35.0بعد از اجرای موفق دستور kubeadm init پوشه etc/kubernetes ساخته می شود. محتویات این پوشه را در زیر مشاهده می کنید:-rw-------. 1 root root 5637 Feb 25 15:26 admin.conf
-rw-------. 1 root root 5665 Feb 25 15:26 controller-manager.conf
-rw-r--r--. 1 root root   91 Feb 19 04:11 kubelet-systemd.conf
-rw-------. 1 root root 1965 Feb 25 15:28 kubelet.conf
drwxr-xr-x. 2 root root  113 Feb 25 15:26 manifests
drwxr-xr-x. 3 root root 4096 Feb 25 15:26 pki
-rw-------. 1 root root 5609 Feb 25 15:26 scheduler.conf
-rw-------. 1 root root 5661 Feb 25 15:26 super-admin.confدر فایلهای با پسوند conf، همه کانفیگ های مورد نیاز اجزای کلاستر کوبرنتیز از جمله کانفیگ scheduler و kublet و نحوه اتصال آنها به kube api نوشته شده است. توجه داشته باشید همانطور که گفته شد همه ارتباطات کلاستر از طریق kube api صورت می گیرد و ارتباطات با استفاده از certificate هایی که CA تولید می کند، رمز میشوند.حین اجرای دستور kubeadm init فرآیند اجرا بصورت کامل در ترمینال نمایش داده می شود. در صورت اجرای موفقیت آمیز دستور kubeadm init بخش پایانی زیر در ترمینال نمایش داده می شود. این بخش حاوی پیام های مهمی است که با هم آن را بررسی می کنیم.Your Kubernetes control-plane has initialized successfully!

To start using your cluster, you need to run the following as a regular user:

  mkdir -p $HOME/.kube
  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  sudo chown $(id -u):$(id -g) $HOME/.kube/config

Alternatively, if you are the root user, you can run:

  export KUBECONFIG=/etc/kubernetes/admin.conf

You should now deploy a pod network to the cluster.
Run &quot;kubectl apply -f [podnetwork].yaml&quot; with one of the options listed at:
  https://kubernetes.io/docs/concepts/cluster-administration/addons/

Then you can join any number of worker nodes by running the following on each as root:

kubeadm join 192.168.65.13:6443 --token 7m53p1.68r7728rdnu9fidg \
        --discovery-token-ca-cert-hash sha256:2d341a0bcbe14f4f366b297ac8bd3f12be21c17883ef5d179f841c15009a57b7
خط 1: Kubernetes control-plane یا همان Master Node با موفقیت راه اندازی شد.خط 3 تا 11: همه اطلاعات مربوط به کاربر ادمین کوبرنتیز در فایل admin.conf قرار گرفته است. این فایل یک فایل مهم است و هر شخصی که این فایل را داشته باشد می تواند بعنوان ادمین کوبرتیز باشد.خط 5 تا 7 می گوید که اگر شما بعنوان ادمین کوبرنتیز هستید، یک پوشه مخفی با نام kube برای خودتان بسازید و فایل admin.conf را به آن کپی کنید و بعدا از این طریق آن را مورد استفاده قرار دهید.در روش جایگزین، خط 11 می گوید که می توانید یک variable با نام KUBECONFIG تعریف کنید و مقدار آن را برابر با مسیر فایل admin.conf قرار دهید. هر کسی که این variable را داشته باشد می تواند به فایل admin.conf دسترسی داشته و بعنوان ادمین کوبرنتیز باشد.با انتخاب و اجرای یکی از دو روش ذکر شده، حالا ما ادمین کلاستر هستیم و می توانیم با اجرای دستورات kubectl، کلاستر کوبرنتیز را مدیریت نماییم.خط 13 تا 15: در بخش بعد توضیح داده خواهد شد.خط 17 تا 20: حالا که کلاستر ما راه اندازی شد با اجرای دستور موجود در خط 19و20 روی یک نود worker می توانیم آن نود را به کلاستر متصل کنیم. به هر تعدادی که بخواهیم می توانیم نود worker به کلاستر کوبرنتیز خود اضافه کنیم.kubeadm join 192.168.65.13:6443 --token 7m53p1.68r7728rdnu9fidg \
        --discovery-token-ca-cert-hash sha256:2d341a0bcbe14f4f366b297ac8bd3f12be21c17883ef5d179f841c15009a57b7توجه داشته باشید که اتصال اولیه worker nodeها به کلاستر توسط توکن انجام می شود. اما بعد از اتصال اولیه، certificate بین آنها و master node ردوبدل می شود و از این پس ارتباط بین آنها با certificate انجام می گیرد.برای مشاهده لیست توکن ها می توانید از دستور زیر استفاده کنید:kubeadm token listاین توکن ها مدت انقضایی در حدود 24 ساعت دارند و بعد از منقضی شدن نمی توان از آنها استفاده کرد.برای تولید توکن جدید می توانید از دستور زیر استفاده کنید:kubeadm token create --print-join-commandپارامتر print-join-command باعث می شود علاوه بر تولید توکن جدید، join-command مربوط به آن هم نمایش داده شود.3. Setup CNICNI: Container Network Interfaceدستور زیر لیست همه Podها را نشان می دهد:kubectl get po -Aبعد از اجرای kubeadm init و راه اندازی کلاستر کوبرنتیز، لیست پادها بصورت زیر می باشند:[root@MASTER-01 kubernetes]# kubectl get po -A
NAMESPACE     NAME                                READY   STATUS    RESTARTS   AGE
kube-system   coredns-7d764666f9-pwjgn            0/1     Pending   0          136m
kube-system   coredns-7d764666f9-qrqvv            0/1     Pending   0          135m
kube-system   etcd-master-01                      1/1     Running   0          137m
kube-system   kube-apiserver-master-01            1/1     Running   0          137m
kube-system   kube-controller-manager-master-01   1/1     Running   0          137m
kube-system   kube-proxy-xp7vx                    1/1     Running   0          136m
kube-system   kube-scheduler-master-01            1/1     Running   0          137metcd, kube-apiserver, kube-controller-manager, kube-proxy و kube-scheduler پادهای سیستمی هستند که روی نود مستر (Control-plane) اجرا می شوند و همانگونه که در ستون READY مشاهده می شود، همه آنها در حال اجرا می باشند. اما پاد coredns که دو نسخه از آن هم موجود می باشد می تواند روی master node یا روی worker node اجرا شود.مانند container runtime، در زمینه Networking هم خود kubernetes، ابزاری را توسعه نداده است. در عوض یک اینترفیس (cni) ایجاد کرده است و هر ابزاری که این اینترفیس را پیاده سازی کند می تواند بعنوان مدیریت کننده شبکه کلاستر استفاده شود. لیستی از این ابزارها در سایت kubernetes در بخش Networking and Network Policy آورده شده است.یکی از ابزارهای معرفی شده در این زمینه Calico می باشد. (برای محیط production بهتر است از Cilium بجای Calico استفاده شود.)راهنمای کامل نصب کالیکو در سایت آن به آدرس زیر وجود دارد:https://docs.tigera.io/calico/latest/getting-started/kubernetes/self-managed-onprem/onpremisesInstall Calico with Kubernetes API datastore, 50 nodes or lessDownload the Calico networking manifest for the Kubernetes API datastore.curl https://raw.githubusercontent.com/projectcalico/calico/v3.31.4/manifests/calico.yaml -OIf you are using pod CIDR 192.168.0.0/16, skip to the next step. If you are using a different pod CIDR with kubeadm, no changes are required — Calico will automatically detect the CIDR based on the running configuration. For other platforms, make sure you uncomment the CALICO_IPV4POOL_CIDR variable in the manifest and set it to the same value as your chosen pod CIDR.Customize the manifest as necessary.Apply the manifest using the following command.kubectl apply -f calico.yamlطبق مستندات نصب کالیکو، ما فایل calico.yaml را دانلود می کنیم و مقدار CALICO_IPV4POOL_CIDR را برابر با مقداری که موقع kubeadm init وارد کرده بودیم قرار می دهیم.# - name: CALICO_IPV4POOL_CIDR
#   value: &quot;192.168.0.0/16&quot;تبدیل می شود به:- name: CALICO_IPV4POOL_CIDR
  value: &quot;10.96.0.0/12&quot;در گام بعدی می توانیم تغییرات دلخواه خود را در فایل calico.yaml بدهیم. به عنوان مثال می توانیم آدرس همه imageها را از مقدار اصلی به آدرس repository خود تغییر دهیم.و در آخر با اجرای دستور زیر این فایل manifest را در کلاستر اعمال می کنیم:kubectl apply -f calico.yamlوقتی این دستور اجرا می شود، kubectl مقدار فایل manifest را تبدیل به json کرده و آن را با فراخوانی REST API به kubeapi می فرستد. kubeapi بعد از دریافت مقدار json آن را در دیتابیس ثبت می کند. سپس اگر نیاز هست پادی بالا بیاید، kubeapi به scheduler دستور بالا آمدن پاد را می دهد. scheduler مجددا از طریق kubeapi دستور میدهد به kubelet.kubelet از طریق containerd اقدام به ساخت image می کند، سپس آن را تبدیل به Pod کرده و تحویل می دهد.حالا مجددا با اجرای دستور kubectl get po -A لیست پادهای موجود در کلاستر را مشاهده می کنیم:[root@MASTER-01 sources]# kubectl get po -A
NAMESPACE     NAME                                     READY   STATUS  
kube-system   calico-kube-controllers-9dff488b-6kbvv   1/1     Running 
kube-system   calico-node-dff24                        1/1     Running
kube-system   calico-node-pbjmj                        1/1     Running
kube-system   coredns-7d764666f9-pwjgn                 1/1     Running 
kube-system   coredns-7d764666f9-qrqvv                 1/1     Running 
kube-system   etcd-master-01                           1/1     Running 
kube-system   kube-apiserver-master-01                 1/1     Running 
kube-system   kube-controller-manager-master-01        1/1     Running 
kube-system   kube-proxy-v6zgz                         1/1     Running 
kube-system   kube-proxy-xp7vx                         1/1     Running 
kube-system   kube-scheduler-master-01                 1/1     Running 
برای مشاهده وضعیت یک پاد می توانیم از دستور زیر استفاده کنیم:kubectl describe po -n kube-system calico-node-dff24پارامتر اول بعد از n- نام namespace و پارامتر بعدی نام پاد می باشد.برای مشاهده وضعیت همه نودهای کلاستر از دستور زیر استفاده می کنیم:kubectl get noبرای مشاهده اینکه هر پادی روی چه نودی اجرا شده، از دستور زیر استفاده می کنیم:kubectl get po -A -o wideمنابع:https://kubernetes.io/docs/concepts/cluster-administration/addons/https://www.tigera.io/tigera-products/calico/https://docs.tigera.io/calico/latest/getting-started/kubernetes/self-managed-onprem/onpremises</description>
                <category>فرهاد صادقی</category>
                <author>فرهاد صادقی</author>
                <pubDate>Fri, 27 Feb 2026 12:05:25 +0330</pubDate>
            </item>
                    <item>
                <title>آموزش Kubernetes - قسمت سوم</title>
                <link>https://virgool.io/@farhad.sadeghi/%D8%A2%D9%85%D9%88%D8%B2%D8%B4-kubernetes-%D9%82%D8%B3%D9%85%D8%AA-%D8%B3%D9%88%D9%85-nksz9y3y2bzj</link>
                <description>مراحل نصب Kubernetes1. Install Container RuntimeYou need to install a container runtime into each node in the cluster so that Pods can run there.Kubernetes 1.35 requires that you use a runtime that conforms with the Container Runtime Interface (CRI).Container runtime های عمومی مختلفی قابلیت استفاده در Kubernetes دارند:containerdCRI-ODocker EngineMirantis Container Runtimeتوجه:نسخه‌های Kubernetes قبل از v1.24 شامل یک یکپارچگی مستقیم با Docker Engine بودند، این کار با استفاده از کامپوننتی به نام dockershim انجام می شد. این یکپارچگی مستقیمِ ویژه دیگر بخشی از Kubernetes نیست (حذف آن به‌عنوان بخشی از انتشار نسخه v1.20 اعلام شد).Docker Engine در دل خود از containerd استفاده می کند. به همین خاطر، کوبرنتیز در نسخه های جدید تصمیم گرفت خودش به صورت مستقیم از containerd به عنوان container runtime استفاده کند.1.1 Install and configure prerequisitesBy default, the Linux kernel does not allow IPv4 packets to be routed between interfaces. Most Kubernetes cluster networking implementations will change this setting (if needed), but some might expect the administrator to do it for them.Enable IPv4 packet forwardingTo manually enable IPv4 packet forwarding:# sysctl params required by setup, params persist across reboots
cat &lt;&lt;EOF | sudo tee /etc/sysctl.d/k8s.conf
net.ipv4.ip_forward = 1
EOF

# Apply sysctl params without reboot
sudo sysctl --system
Verify that net.ipv4.ip_forward is set to 1 with:sysctl net.ipv4.ip_forward1.2 Install containerdبرای نصب containerd سه روش وجود دارد:download and install binary filesusing yumcompile from source codeما روش اول یعنی دانلود و نصب فایل binary را در پیش خواهیم گرفت که خود شامل مراحل زیر است:1- download and install containerd and write linux servicetar Cxzvf /usr/local/ containerd-2.2.1-linux-amd64.tar.gz
cp containerd.service /usr/lib/systemd/system/
systemctl daemon-reload
systemctl enable --now containerdخط اول فایل containerd-2.2.1-linux-arm64.tar.gz را extract کرده و محتویات آن را در پوشه usr/local قرار می دهد. چرا که مسیر پوشه usr/local در PATH$ (مسیر فایلهای اجرایی) وجود دارد و با قرار دادن فایلها داخل آن، در واقع فایلهای باینری containerd نصب می شوند.خط دوم فایل containerd.service را در مسیر usr/lib/systemd/system کپی می کند. داخل فایل containerd.service فایل اجرایی containerd بصورت یک سرویس لینوکسی توصیف شده است. وقتی این فایل در پوشه systemd/system کپی می شود، سرویس توصیف شده نصب شده و در لیست سرویس های لینوکس قرار می گیرد.در لینوکس ما وقتی یک برنامه را تبدیل به سرویس می کنیم مانند windows service ها در ویندوز امکان شروع، پایان و یا راه اندازی خودکار آن سرویس وجود دارد و ما می توانیم با کامند systemctl آن را کنترل کنیم.خط سوم لیست سرویس ها را reload می کند تا سرویس containerd که جدیدا نصب شده است، در لیست سرویس ها قرار گیرد.خط چهارم سرویس containerd را auto start می کند.2- download and install runcinstall -m 755 runc.amd64 /usr/local/sbin/runcاین خط فایل run.amd64 را در مسیر usr/local/sbin/runc کپی می کند و دسترسی سطح 755 را هم برای آن تنظیم می کند تا برای کاربر root قابل اجرا باشد.کامند install فایل را کپی می کند و permission های آن را نیز تنظیم می کند. هر جا ما نیاز داشته باشیم این دو کار را باهم انجام دهیم می توانیم از کامند install استفاده کنیم.3- download and install cni-plugin(cni: container network interface)mkdir -p /opt/cni/bin
tar Cxzvf /opt/cni/bin/ cni-plugins-linux-amd64-v1.9.0.tgzخط اول مسیر opt/cni/bin را ایجاد می کند. پارامتر p امکان ایجاد هر پوشه و پوشه های داخل آن را در صورتی که وجود نداشته باشند فراهم می کند. با اجرای این خط پوشه cni داخل پوشه opt ایجاد می شود و پوشه bin نیز داخل پوشه cni ایجاد می شود.خط دوم فایل cni-plugins-linux-amd64-v1.9.0.tgz را در مسیر opt/cni/bin که در خط اول ایجاد شد extract می کند.2. Install Kubeadm, Kubectl, Kubeletkubeadm: the command to bootstrap the cluster.kubectl: the command line util to talk to your cluster.kubelet: the component that runs on all of the machines in your cluster and does things like starting pods and containers.برای راه اندازی کلاستر کوبرنتیز باید kubeadm را نصب کنیم. یعنی اگر ما بخواهیم یک کلاستر کوبرنتیز بالا بیاوریم باید با کامند لاین kubeadm این کار را انجام دهیم.Kubectl (The Kubernetes command-line tool) کامند لاین کوبرنتیز است. یعنی ما command را به آن می دهیم و این پکیج آن را به Kubernetes Api منتقل می کند. این ابزار امکان ارتباط با کلاستر کوبرنتیز و اجرای دستورات روی آن را فراهم می کند. با استفاده از kubectl شما می توانید برنامه ها را deploy کنید، منابع کلاستر کوبرنتیز را بازرسی و مدیریت کنید و لاگ ها را مشاهده نمایید.kubectl روی سیستم عامل های ویندوز، لینوکس و مک قابلیت نصب شدن دارد. من در اینجا نحوه نصب آن روی نود لینوکس را شرح می دهم.2.1 Swap configurationفضای swap بخشی از هارد دیسک است که در صورت نیاز بخشی از RAM می تواند در آن قرار گیرد. مثلا وقتی فضای RAM پر شود سیستم عامل بخشی از آن را روی فضای swap در هارددیسک کپی می کند تا فضای خالی روی RAM برای ادامه کار داشته باشد.نسخه های قدیمی کوبرنتیز برای اینکه performance بهتری داشته باشند از swap پشتیبانی نمی کردند. نسخه های جدید کوبرنتیز هم به شرط تعریف swapBehavior از آن پشتیبانی می کنند. اما همچنان توصیه این است که این قابلیت غیرفعال شود.swapoff -a
topخط اول swap را غیرفعال می کند.با اجرای خط دوم می توانیم وضعیت حافظه swap را مشاهده کنیم.بعد از ریستارت کردن سیستم وضعیت swap دوباره برمی گردد. برای اینکه تغییرات همیشگی باشد باید در فایل fstab خط مربوط به swap کامنت شود.vim /etc/fstab2.2 Set SELinux to permissive modeSELinux (Security-Enhanced Linux) اجازه نمی دهد که هر پورتی به هر پروسسی bind شود. kubernetes با SELinux یکپارچگی ندارد. به همین منظور توصیه می کند آن را غیرفعال کنیم و فقط در صورتی آن را فعال نگه داریم که به نحوه کانفیگ کردن آن تسلط کافی داشته باشیم.These instructions are for Kubernetes 1.35.# Set SELinux in permissive mode (effectively disabling it)
sudo setenforce 0
sudo sed -i &#039;s/^SELINUX=enforcing$/SELINUX=permissive/&#039; /etc/selinux/configsetenforce 1 وضعیت را به Enforcing تغییر می دهد و setenforce 0 وضعیت را به Premissive تغییر می دهد. SELinux در حالت premissive فقط پروسس ها و پورت ها را مانیتور می کند ولی مانع اجرای آنها نمی شود.برای نمایش وضعیت فعلی می توانیم از دستور getenforce استفاده کنیم.2.3 Add the Kubernetes yum repositoryآدرس repository کوبرنتیز https://pkgs.k8s.io/core:/stable:/v1.35/rpm می باشد یعنی همه rpm های کوبرنتیز در این آدرس است. با دستور زیر، این آدرس به لیست ریپوزیتوری ها اضافه می شود. (توجه داشته باشید که این آدرس بخاطر تحریم ها از ایران قابل دسترس نیست)# This overwrites any existing configuration in /etc/yum.repos.d/kubernetes.repo
cat &lt;&lt;EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://pkgs.k8s.io/core:/stable:/v1.35/rpm/
enabled=1
gpgcheck=1
gpgkey=https://pkgs.k8s.io/core:/stable:/v1.35/rpm/repodata/repomd.xml.key
exclude=kubelet kubeadm kubectl cri-tools kubernetes-cni
EOFبعد از اجرای دستور بالا باید kubernetes.repo به آدرس etc/yum.repos.d اضافه شده باشد.خط شماره دو:cat &lt;&lt;EOF | sudo tee /etc/yum.repos.d/kubernetes.repo🔹 cat &lt;&lt;EOFاین ساختار به آن Here Document می‌گویند.یعنی هر متنی که تا رسیدن به EOF نوشته شود، به عنوان ورودی به دستور cat داده می‌شود.🔹 |خروجی cat را به دستور بعدی می‌فرستد (pipe).🔹 sudo tee /etc/yum.repos.d/kubernetes.repoدستور tee متن دریافتی را داخل فایل مشخص‌شده می‌نویسد.چون مسیر /etc/yum.repos.d/ نیاز به دسترسی روت دارد، از sudo استفاده شده است.📌 نتیجه: یک فایل به نام/etc/yum.repos.d/kubernetes.repoساخته یا بازنویسی می‌شود.بخش دوم: محتوای فایل ریپو[kubernetes]
name=Kubernetes
baseurl=https://pkgs.k8s.io/core:/stable:/v1.35/rpm/
enabled=1
gpgcheck=1
gpgkey=https://pkgs.k8s.io/core:/stable:/v1.35/rpm/repodata/repomd.xml.key
exclude=kubelet kubeadm kubectl cri-tools kubernetes-cniاین تنظیمات مربوط به مخزن رسمی Kubernetes برای سیستم‌های مبتنی بر yum/dnf (مثل CentOS، Red Hat Enterprise Linux و Fedora) است.2.4 Install Kubeadm, Kubectl, Kubeletبا اجرای دستور زیر kubeadm, kubectl و kubelet از ریپوزیتوری کوبرنیتز دریافت و نصب می شوند.sudo yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetesتوجه داشته باشید که ریپوزیتوری های kubernetes برای کشور ما بسته است. شما می توانید با ویرایش فایل resolve.conf و تنظیم DNS Server شکن این تحریم را دور بزنید.vi /etc/resolv.conf

#change resolv.conf file
nameserver 178.22.122.100
nameserver 185.51.200.2اگر نیاز داشته باشید که پکیج های rpm نصب را دانلود کنید و بعدا بصورت آفلاین روی سرورهای دیگر خود نصب کنید، می توانید با دستور زیر آنها را در مسیر دلخواه خود دانلود کنید:sudo yum install --downloadonly --downloaddir=/mysources/ -y kubelet kubeadm kubectl --disableexcludes=kubernetesپکیج های rpm دانلود شده را با دستور زیر می توان نصب کرد:sudo yum install -y kubeadm-1.35.0-0x86-64.rpm kubectl-1.35.0-0x86-64.rpm3. Configuring cgroup driverدر زمینه مدیریت منابع (Resource management) کانتینرها، دو مفهوم وجود دارد:namespace: اجازه نمی دهد IPها، MountPoint ها، Porccess Id های یکسان داشته باشیم.Cgroup: منابع را از لحاظ CPU، رم و ... مدیریت و محدود می کند.وقتی می گوییم Pod شماره یک باید 2 گیگ رم داشته باشد، این مطلب را هم باید containerd متوجه باشد و هم kubelet. بنابراین هر دوی آنها باید با یک زبان مشترک صحبت بکنند. cgroup driver این کار را انجام می دهد. در واقع هر دوی آنها از یک درایور برای مدیریت منابع استفاده می کنند و آن cgroup driver است.در Kubernetes برای cgroup driver دو گزینه وجود دارد:cgroupfssystemdدر لینوکس systemd اولین سرویسی است که بالا می آید و فرآیند بوت کرنل (init system) و بالا آمدن سرویس های دیگر را systemd انجام می دهد. طبق پیشنهاد Kubernetes، در سیستم هایی که systemd بعنوان init system بکار می رود، توصیه نمی شود از cgroupfs بعنوان cgroup driver استفاده شود و بهتر است بجای آن از systemd cgroup driver استفاده شود.3.1 Configuring containerd&#039;s cgroup driverدر گام اول ما می خواهیم systemd را بعنوان cgroup driver سرویس containerd تنظیم کنیم:#How to change containerd cgroup driver:
--------------------------------------------
mkdir /etc/containerd
containerd config default | tee /etc/containerd/config.toml
vi /etc/containerd/config.toml
#change SystemdCgroup = true
systemctl restart containerdدر خط چهارم یک پوشه برای تنظیمات containerd ساخته می شود.در خط پنجم کانفیگ فعلی (پیش فرض) containerd گرفته شده و در فایل etc/containerd/config.toml نوشته می شود.خط ششم فایل config.toml را باز می کند.در این فایل با مقدار پارامتر SystemCgroup را از false به true تغییر داده و فایل را ذخیره می کنیم.برای اینکه تغییرات در containerd اعمال شود، در خط 8 سرویس containerd را یک بار ریستارت می کنیم.تا اینجای کار systemd بعنوان cgroup برای containerd تنظیم شد.3.2 Configuring kubelet&#039;s cgroup driverدر گام بعد ما می خواهیم systemd را بعنوان cgroup driver سرویس kubelet تنظیم کنیم:#How to change kubelet cgroup driver:
--------------------------------------------
vim /etc/kubernetes/kubelet-systemd.confابتدا فایل kubelet-systemd.conf را در مسیر etc/kubernetes ایجاد می کنیم و سپس محتوای زیر را در آن می نویسیم و ذخیره می کنیم:apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
cgroupDriver: systemdحالا باید فایل سرویس kubelet را باز می کنیم و به آن بفهمانیم که از این به بعد فایل کانفیگی که ساختیم را هم لود کن.vim /usr/lib/systemd/system/kubelet.serviceتوجه: برای اینکه بدانیم فایل kubelete.service در چه مسیری قرار دارد می توانیم از دستور زیر استفاده کنیم.systemctl status kubeletدر فایل kubelet.service به انتهای خط ExecStart عبارت زیر را اضافه می کنیم و به این ترتیب سرویس kubelet موقع اجرا شدن، فایل کانفیگی که ما ایجاد کردیم را اعمال می کند.--config /etc/kubernetes/kubelet-systemd.confبه این ترتیب سکشن Service در فایل kubelet.service به شکل زیر خواهد بود:[Service]
ExecStart=/usr/bin/kubelet --config /etc/kubernetes/kubelet-systemd.conf
Restart=always
StartLimitInterval=0
RestartSec=10 در انتها یکبار سرویس kubelet را ریستارت می کنیم.systemctl restart kubeletمنابع:https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/http://kernel.org/https://kubernetes.io/docs/reference/node/kernel-version-requirements/https://kubernetes.io/docs/setup/production-environment/container-runtimeshttps://github.com/containerd/containerd/blob/main/docs/getting-started.md</description>
                <category>فرهاد صادقی</category>
                <author>فرهاد صادقی</author>
                <pubDate>Thu, 19 Feb 2026 15:01:23 +0330</pubDate>
            </item>
                    <item>
                <title>آموزش Kubernetes - قسمت دوم</title>
                <link>https://virgool.io/@farhad.sadeghi/%D8%A2%D9%85%D9%88%D8%B2%D8%B4-kubernetes-%D9%82%D8%B3%D9%85%D8%AA-%D8%AF%D9%88%D9%85-cfibq3plqm63</link>
                <description>کلاستر Kubernetes چیست؟برای راه اندازی کلاستر کوبرنتیز در محیط تست به حداقل 3 نود نیاز است؛ یک نود Master و دو نود Worker. ولی در محیط محصول (production environment) بهتر است حداقل 6 نود داشته باشیم که 3 تای آنها بعنوان Master Node و 3 تای آنها بعنوان Worker Node در نظر گرفته می شوند.حداقل منابع مورد نیاز برای هر نود به شرح زیر می باشد:CPU: 2 CoreRAM: 2 GiBHDD: 40 GiBنودهای Master وظیفه مدیریت کلاستر کوبرنتیز را برعهده دارند. نودهای Worker همانطور که از اسمشان پیداست، وظیفه اجرای برنامه های کاربردی را برعهده دارند. برنامه های کاربردی در قالب Pod روی نودهای Worker اجرا می شوند.کوبرنتیز به خودی خود یک میکروسرویس است یعنی خودش از یک سری کامپوننت و سرویس تشکیل شده است که با هم در ارتباط می باشند و با همکاری هم سرویس کوبرنتیز ارائه می شود.کامپوننت های مورد استفاده در هر یک از نودهای master و worker به شرح زیر می باشند:Control Plane Manager (Master Node):• Kube-apiServer• Etcd• Kube-Scheduler• Kube-ControllerWorker Node:• Kube-Proxy• Kubelet• Container Runtimeبرخی از این ابزارها و کامپوننت ها توسط خود Kubernetes پیاده سازی و ایجاد شده اند مانند Kube-Scheduler، Kube-Controller ، Kube-Proxy و Kube-apiServer.اما برخی دیگر از این ها ابزارهای open source می باشند که Kubernetes از آنها استفاده می کند مانند Etcd که یک دیتابیس Key/Value Store می باشد و یا Containerd که یک Container Runtime می باشد و Kubernetes از آن استفاده می کند.ساختار کلاستر کوبرنتیزControl Plane ComponentsManage the overall state of the cluster:kube-apiserverThe core component server that exposes the Kubernetes HTTP API. (port 6443)etcdConsistent and highly-available key value store for all API server data.kube-schedulerLooks for Pods not yet bound to a node, and assigns each Pod to a suitable node.kube-controller-managerRuns controllers to implement Kubernetes API behavior.cloud-controller-manager (optional)Integrates with underlying cloud provider(s).Node ComponentsRun on every node, maintaining running pods and providing the Kubernetes runtime environment:kubeletEnsures that Pods are running, including their containers.kube-proxy (optional)Maintains network rules on nodes to implement Services.Container runtimeSoftware responsible for running containers.🛇 This item links to a third party project or product that is not part of Kubernetes itself.قبلا Kubernetes از Docker بعنوان Container runtime استفاده می کرد، از آنجایی که داکر در دل خود از Containerd استفاده می کند، Kubernetes تصمیم گرفت از Containerd بجای Docker استفاده کند و در نسخه های جدید کوبرنتیز از Containerd بعنوان Container runtime استفاده می شود.Your cluster may require additional software on each node; for example, you might also run systemd on a Linux node to supervise local components.AddonsAddons extend the functionality of Kubernetes. A few important examples include:DNSFor cluster-wide DNS resolution.Web UI (Dashboard)For cluster management via a web interface.Container Resource MonitoringFor collecting and storing container metrics.Cluster-level LoggingFor saving container logs to a central log store.در پست بعدی، نحوه نصب و راه اندازی کلاستر کوبرنتیز را آموزش خواهیم داد.</description>
                <category>فرهاد صادقی</category>
                <author>فرهاد صادقی</author>
                <pubDate>Fri, 06 Feb 2026 16:26:37 +0330</pubDate>
            </item>
                    <item>
                <title>آموزش Kubernetes - قسمت اول</title>
                <link>https://virgool.io/@farhad.sadeghi/%D8%A2%D9%85%D9%88%D8%B2%D8%B4-kubernetes-%D9%82%D8%B3%D9%85%D8%AA-%D8%A7%D9%88%D9%84-uskkwfhoxm8o</link>
                <description>راه اندازی kubernetes در محیط تست لوکالSetting up local Kubernetes environmentsRunning Kubernetes locally gives you a safe environment to learn and experiment. You can set up and tear down clusters without worrying about costs or affecting production systems.kindkind (Kubernetes IN Docker) runs Kubernetes clusters using Docker containers as nodes. It is lightweight and designed specifically for testing Kubernetes itself, but works great for learning too.minikubeminikube runs a single-node Kubernetes cluster on your local machine. It supports multiple container runtimes and works on Linux, macOS, and Windows.Other local options🛇 This item links to a third party project or product that is not part of Kubernetes itself.There are several third-party tools that can also run Kubernetes locally. Kubernetes does not provide support for these tools, but they may work well for your learning needs:Docker Desktop can run a local Kubernetes clusterPodman Desktop can run a local Kubernetes clusterRancher Desktop provides Kubernetes on your desktopMicroK8s runs a lightweight Kubernetes clusterRed Hat CodeReady Containers (CRC) runs a minimal OpenShift cluster locally (OpenShift is Kubernetes-conformant)Refer to each tool&#039;s documentation for setup instructions and support.Using online playgrounds🛇 This item links to a third party project or product that is not part of Kubernetes itself.Online Kubernetes playgrounds let you try Kubernetes without installing anything on your computer. These environments run in your web browser:Killercoda provides interactive Kubernetes scenarios and a playground environmentPlay with Kubernetes gives you a temporary Kubernetes cluster in your browserThese platforms are useful for quick experiments and following tutorials without local setup.</description>
                <category>فرهاد صادقی</category>
                <author>فرهاد صادقی</author>
                <pubDate>Fri, 06 Feb 2026 16:00:54 +0330</pubDate>
            </item>
                    <item>
                <title>Clean Architecture</title>
                <link>https://virgool.io/@farhad.sadeghi/clean-architecture-m7fd0ucxgwnk</link>
                <description>Core (Domain Model) ProjectIn Clean Architecture, the central focus should be on Entities and business rules.In Domain-Driven Design, this is the Domain Model.This project should contain all of your Entities, Value Objects, and business logic.Entities that are related and should change together should be grouped into an Aggregate.Entities should leverage encapsulation and should minimize public setters.Entities can leverage Domain Events to communicate changes to other parts of the system.Entities can define Specifications that can be used to query for them.For mutable access, Entities should be accessed through a Repository interface.Read-only ad hoc queries can use separate Query Services that don&#039;t use the Domain Model.Use Cases (Application Services) ProjectIn Clean Architecture, the Use Cases (or Application Services) project is a relatively thin layer that wraps the domain model.Use Cases are typically organized by feature. These may be simple CRUD operations or much more complex activities.Use Cases should not depend directly on infrastructure concerns, making them simple to unit test in most cases.Use Cases are often grouped into Commands and Queries, following CQRS.Having Use Cases as a separate project can reduce the amount of logic in UI and Infrastructure projects.For simpler projects, the Use Cases project can be omitted, and its behavior moved into the UI project, either as separate services or MediatR handlers, or by simply putting the logic into the API endpoints.Infrastructure ProjectIn Clean Architecture, Infrastructure concerns are kept separate from the core business rules (or domain model in DDD).The only project that should have code concerned with EF, Files, Email, Web Services, Azure/AWS/GCP, etc is Infrastructure.Infrastructure should depend on Core (and, optionally, Use Cases) where abstractions (interfaces) exist.Infrastructure classes implement interfaces found in the Core (Use Cases) project(s).These implementations are wired up at startup using DI. In this case using Microsoft.Extensions.DependencyInjection and extension methods defined in each project.Resources and Samples:https://github.com/mimohammadi/CleanArchitectureTempByMinaMohammadihttps://github.com/ardalis/CleanArchitecturehttps://github.com/jasontaylordev/CleanArchitecturehttps://vrgl.ir/woLc2https://vrgl.ir/g2AKj</description>
                <category>فرهاد صادقی</category>
                <author>فرهاد صادقی</author>
                <pubDate>Wed, 04 Feb 2026 13:49:56 +0330</pubDate>
            </item>
                    <item>
                <title>پیام‌های ناموفق و Retry در RabbitMQ</title>
                <link>https://virgool.io/@farhad.sadeghi/%D9%BE%DB%8C%D8%A7%D9%85-%D9%87%D8%A7%DB%8C-%D9%86%D8%A7%D9%85%D9%88%D9%81%D9%82-%D9%88-retry-%D8%AF%D8%B1-rabbitmq-lyftskoj7ucy</link>
                <description>✅ مشاهده پیام‌های ناموفق در RabbitMQ❌ واقعیت مهمRabbitMQ به‌صورت پیش‌فرض جایی برای دیدن پیام‌های ناموفق نداره.اگر پیام fail بشه و درست هندل نشه، ممکنه برای همیشه حذف بشه.✔ راه‌حل استاندارد: Dead Letter Queue (DLQ)پیام چه زمانی می‌ره DLQ؟reject یا nack با requeue=falseاتمام TTLپر شدن صف (max-length)🔧 تنظیم DLQ روی صف اصلیx-dead-letter-exchange: my.dlx
x-dead-letter-routing-key: dead🔍 چطور پیام‌های ناموفق رو ببینیم؟فعال بودن RabbitMQ Management Pluginرفتن به UI → Queuesباز کردن DLQدکمه Get Messages📌 مناسب دیباگ و بررسی، نه مصرف دائمی📎 اطلاعات مهم داخل پیام DLQدر headerها:x-death.reason (علت fail)x-death.count (چند بار fail شده)x-death.exchangex-death.queueاگر DLQ درست مدیریت نشه، می‌تونه حافظه یا دیسک سرور RabbitMQ رو پر کنه و باعث down شدن سرور بشه.ولی خبر خوب اینه که با چند تا تنظیم ساده، این ریسک تقریباً صفر می‌شه 👇چرا DLQ خطرناک می‌شه؟DLQ دقیقاً مثل هر صف دیگه‌ایه. اگر:پیام‌ها دائماً fail بشنمصرف‌کننده‌ای برای DLQ نداشته باشییا limit نذاریاون صف بی‌نهایت رشد می‌کنه.نتیجه:اگر پیام‌ها transient باشن → RAM پر می‌شهاگر persistent باشن → Disk پر می‌شهRabbitMQ وقتی به limit برسه:شروع به block کردن publisher می‌کنهیا بدتر: کل node از دسترس خارج می‌شه ❌چطور DLQ رو امن کنیم؟ (Best Practices)1️⃣ حتماً برای DLQ محدودیت بذار (خیلی مهم)x-max-length: 10000
x-overflow: drop-headیا بر اساس حجم:x-max-length-bytes: 100MB📌 این باعث می‌شه پیام‌های خیلی قدیمی حذف بشن.2️⃣ روی DLQ هم TTL بذارx-message-ttl: 604800000مثلاً بعد از ۷ روز خودکار پاک بشن.3️⃣ پیام‌های DLQ رو persistent نکن (در صورت امکان)اگر فقط برای debug هست:delivery_mode = 1  // transient4️⃣ حتماً alarm های RabbitMQ رو مانیتور کنRabbitMQ وقتی منابع کم می‌شن alarm می‌زنه:memory_alarmdisk_alarmو publisher رو block می‌کنه.حتماً این‌ها رو مانیتور کن:rabbitmqctl statusیا در UI:Overview → Node details🔁 Retry در RabbitMQ (به روش درست)DLQ برای retry نیست ❌اشتباه رایج:«بیایم پیام‌های DLQ رو دوباره publish کنیم»❌ روش اشتباهnack + requeue=trueاین کار باعث loop و انفجار پیام می‌شه 💣برای retry درست از:Retry QueueDelayed Exchangeیا backoff strategyاستفاده کن.الگوی امن پیشنهادیMain Queue
   ↓ fail
Retry Queue (TTL + DLX)
   ↓ expire
Main Queue
   ↓ fail after N tries
DLQ (TTL + max-length)🔧 Retry Queuex-message-ttl: 30000
x-dead-letter-exchange: main.exchange📌 پیام بعد از ۳۰ ثانیه دوباره به صف اصلی برمی‌گرده🔢 محدود کردن retryبا header مثل x-retry-countیا x-death.countمنطق:retry &lt; N → retry
retry ≥ N → DLQ⏳ Backoff (خیلی مهم)چند retry queue با TTL مختلف:retry 5sretry 30sretry 2m🧠 چه پیام‌هایی retry بشن؟✅ retrytimeoutnetwork errorservice unavailable❌ چه پیام هایی مستقیم به DLQ می روند؟validation errorbusiness rule failmessage خراب🔐 نکته حیاتی: IdempotencyRetry = احتمال پیام تکراریconsumer باید:idempotent باشهیا deduplication داشته باشه</description>
                <category>فرهاد صادقی</category>
                <author>فرهاد صادقی</author>
                <pubDate>Mon, 05 Jan 2026 19:45:06 +0330</pubDate>
            </item>
                    <item>
                <title>طراحی UI و UX (رابط کاربری و تجربه کاربری)</title>
                <link>https://virgool.io/@farhad.sadeghi/%D8%AA%D9%81%D8%A7%D9%88%D8%AA-ui-%D9%88-ux-%D8%B1%D8%A7%D8%A8%D8%B7-%DA%A9%D8%A7%D8%B1%D8%A8%D8%B1%DB%8C-%D9%88-%D8%AA%D8%AC%D8%B1%D8%A8%D9%87-%DA%A9%D8%A7%D8%B1%D8%A8%D8%B1%DB%8C-rsftegurce1o</link>
                <description>طراحی UI/UX به معنای طراحی رابط کاربری و تجربه کاربری است و هدف آن ایجاد محصولاتی است که هم از نظر بصری جذاب و هم از نظر تعامل کاربر دلپذیر باشند.تفاوت بین طراحی UI و UXتفاوت UI و UXاگر توی وب UI vs UX رو جستجو کنین یکی از مثال‌های اصلی که زیاد باهاش روبرو می‌شوید همین مثال سس HEINZ هست که می‌گه سمت چپیه ظاهر زیبایی داره و به UI اشاره داره اما سمت راستیه علاوه بر ظاهر زیبا، چون برعکس طراحی شده همیشه مایه سس در پایین ظرف و نزدیک درب خروجیه و در نتیجه راحت‌تر سس میاد بیرون و خوب کاربردی‌تره و تجربه بهتری منتقل می‌کنه.رابط کاربری (UI) و تجربه کاربری (UX) دو رشته جداگانه هستند که بر جنبه‌های مختلف تعامل کاربر تمرکز دارند.این دو رشته در بسیاری از جنبه‌ها همپوشانی دارند و به یکدیگر کمک می‌کنند.از آنجایی که صحبت ما در رابطه با طراحی UI/UX هست، بررسی آماری در این زمینه از کشور هند خالی از لطف نیست.رشد کسب‌وکارهای آنلاین در هند (2021-2022)هند در رتبه 20 از 100 کشور برتر در شاخص اکوسیستم استارتاپ جهانی قرار دارد.بیش از 1 میلیون شغل در طراحی UX در سراسر این کشور وجود دارد.81 شرکت هندی در سال 2021 به لیست استارتاپ‌های یونیکورن پیوستند.فهرستی از استارتاپ‌های سرمایه‌گذاری‌کننده در UI/UXUNIQLOYUJ DesignsCLARITIZ INNOVATIONSpread Design and Innovation Pvt Ltd17Sevenبرندهای هندی با رابط کاربری جالب و آسانNYKAAHUNGERBOXCAREER ANNACULT.FITTopprچه کسی می‌تواند طراح تجربه کاربری شود؟هر کسی که حساسیت به رفتار مصرف‌کننده داشته باشد و از ساده‌سازی طراحی لذت ببرد.طراحان و کارآفرینانی که می‌خواهند هویت آنلاین خود را بسازند.مهارت‌های مورد نیاز برای طراح UI و UXتفکر خلاق و حس طراحیدانش زبان طراحی بصریتوانایی رهبری و هماهنگی در توسعه محصولاگر بخواهیم از مدل بهتری استفاده کنیم باید بگیم که UI بخشی از UX محسوب می‌شه و در حقیقت تصمیم، انتخاب و دانشی در UI نیست که رد اون رو نشه در UX پیدا کرد.حتی موضوعاتی مثل انتخاب فونت، رنگ، انتخاب تصاویر و ابعاد و سایه‌ها هم که هر چند در نگاه اول مربوط به UI می‌شن اما می‌تونند بنا به دلایل UXی مجبور به تغییر بشند.خوبه که بدونید UX خودش زیر مجموعه Customer experience و Brand experience محسوب می‌شه.اگر دوست دارید بیشتر در رابطه با تفاوت این مفاهیم بدانید، مقاله زیر را مطالعه کنید:تفاوت UI و UX و CX در چیست؟مراحل طراحی از ایده تا طرح نهاییتحلیل نیازها و جریان کاریابتدا طی جلسه‌ای با حضور افراد تیم و مدیر پروژه، نیازها و جریان کاری کاربر برای استفاده از برنامه تعیین شده و در یک واسط که در شکل زیر به ابتدایی ترین شکل کشیده شده است سعی می شود که مفاهیم و خواسته‌ها را شرح دهیم.شرح نیاز واسط کاربری و جریان تعامل کاربر با برنامهقبل از طراحی: User Flow ترسیم کنیددر ابتدا باید تصویر درستی از صفحات مختلف نرم افزار و نحوه ی تعامل کاربر با آن ها داشته باشید. اگر این اصل را رعایت کنید، طراحی وایرفریم بسیار آسان تر خواهد بود.بطور خلاصه، User Flow مجموعه مراحلی است که کاربر برای رسیدن به یک هدف خاص، طی می‌کند. در حقیقت، &quot;هدف خاص کاربر&quot; در اینجا نقش اساسی دارد؛ چرا که هر کاربر برای رسیدن به یک هدف ممکن است راه های مختلفی را امتحان کند و همین امر باعث می شود تا User Flow همواره یک مسیر خطی تلقی نشود. User Flow، به شما کمک می‌کند تا بدانید چه تعداد وایرفریم باید طراحی کنید و آن ها چگونه باید به یکدیگر متصل شوند؟برای ترسیم User Flow می توانید از شکل های ابتدایی مانند جعبه های مستطیل شکل و فلش استفاده کنید. قلم و کاغذ یا ابزار دیجیتالی فرقی نمی‌کند. در ادامه نوعی از User Flow طراحی شده در نرم افزار بالزامیک را می بینیم:User Flow فرآیند تحویل غذااسکچ زدن رابط کاربریحال با درنظر داشتن اصول گفته شده، یک رابط کاربری برای تعامل با سیستم به عنوان یک مطالعه موردی انجام می دهیم. ممکن است در ابتدا طرح اولیه روی کاغذ زده شده (Sketch) و با گرفتن بازخورد از هم تیم ها و مدیر پروژه اشکالاتی که دارد برطرف شود.اسکچ رابط کاربری برنامه با کاغذ و مدادطراحی وایرفریمدر مرحله طراحی واسط کاربری ابتدا بازخوردها و ایده‌های قبلی که روی کاغذ آورده بودیم را می کشیم تا نقشه راه مان در مراحل بعد باشد. در شکل زیر به ردیف اول (اشکال هندسی توخالی) وایرفریم low-fidelity یا سطح پایین نیز گفته می‌شود.ایجاد پروتوتایپ در ردیف دوم با استفاده از راهنمای طراحی متریال گوگل اقدام به کامل‌تر نمودن پروتوتایپ ها می کنیم که با استفاده از پلت رنگی بنفش که بالای آرت برد ها آورده شده است. با تکیه بر سادگی، زیبایی و در عین حال کاربردپذیری واسط کاربری طراحی ها انجام شده اند.نمایی از برنامه AdobeXD حین طراحی پروتوتایپ های برنامهبرای مطالعه دقیقتر مراحل طراحی نرم افزار و وایرفریم می توانید به مقاله زیر مراجعه کنید:طراحی وایرفریم برای اپ موبایلسیستم های طراحی نرم افزار (Design Systems)سیستم‌های طراحی در نرم‌افزار (Design Systems) به مجموعه‌ای از اصول، الگوها و ابزارها اشاره دارند که به توسعه‌دهندگان و طراحان کمک می‌کنند تا رابط‌های کاربری و تجربه کاربری (UX) بهتری ایجاد کنند. این سیستم‌ها معمولاً شامل اجزای زیر هستند:کتابخانه‌های کامپوننت: مجموعه‌ای از عناصر طراحی مانند دکمه‌ها، فرم‌ها، نوار جستجو و غیره که می‌توانند به راحتی در پروژه‌های مختلف استفاده شوند.راهنماهای طراحی: مستنداتی که اصول طراحی، رنگ‌ها، فونت‌ها و نحوه استفاده از کامپوننت‌ها را توضیح می‌دهند. این راهنماها به حفظ یکپارچگی طراحی در تمام پروژه‌ها کمک می‌کنند.الگوهای طراحی: راه‌حل‌های از پیش تعریف‌شده برای مشکلات رایج در طراحی و توسعه نرم‌افزار. این الگوها می‌توانند شامل الگوهای ناوبری، الگوهای فرم و غیره باشند.ابزارهای طراحی: نرم‌افزارهایی که به طراحان کمک می‌کنند تا طراحی‌های خود را ایجاد و ویرایش کنند. این ابزارها می‌توانند شامل نرم‌افزارهای گرافیکی، پروتوتایپ‌سازی و همکاری باشند.سیستم‌های طراحی ریسپانسیو: طراحی‌هایی که به طور خودکار به اندازه‌های مختلف صفحه نمایش و دستگاه‌ها پاسخ می‌دهند و تجربه کاربری بهتری را فراهم می‌کنند.استفاده از سیستم‌های طراحی می‌تواند به افزایش کارایی، کاهش زمان توسعه و بهبود تجربه کاربری کمک کند. از جمله سیستم‌های طراحی معروف می‌توان به موارد زیر اشاره کرد:Material Design: طراحی شده توسط گوگل، این سیستم بر اساس اصول طراحی متریال و تجربه کاربری مدرن است.Bootstrap: یک فریم‌ورک طراحی وب که شامل مجموعه‌ای از کامپوننت‌ها و الگوهای طراحی برای ایجاد وب‌سایت‌های ریسپانسیو است.Ant Design: یک سیستم طراحی برای برنامه‌های وب و موبایل که توسط علی‌بابا توسعه یافته و بر روی طراحی کاربرپسند تمرکز دارد.Foundation: یک فریم‌ورک طراحی وب که به توسعه‌دهندگان کمک می‌کند تا وب‌سایت‌های ریسپانسیو و قابل دسترس بسازند.Carbon Design System: سیستم طراحی IBM که برای ایجاد تجربه‌های کاربری یکپارچه و مدرن در محصولات و خدمات این شرکت طراحی شده است.Fluent Design System: طراحی شده توسط مایکروسافت، این سیستم بر روی ایجاد تجربه‌های کاربری زیبا و کاربرپسند در محصولات مایکروسافت تمرکز دارد.Salesforce Lightning Design System: یک سیستم طراحی برای ایجاد رابط‌های کاربری در پلتفرم Salesforce که شامل کامپوننت‌ها و الگوهای طراحی است.Atlassian Design Guidelines: سیستم طراحی Atlassian که برای محصولات این شرکت مانند Jira و Confluence طراحی شده است.Grommet: یک فریم‌ورک طراحی برای React که بر روی ایجاد رابط‌های کاربری ریسپانسیو و قابل دسترس تمرکز دارد.Shopify Polaris: سیستم طراحی Shopify که برای ایجاد تجربه‌های کاربری یکپارچه در پلتفرم تجارت الکترونیک این شرکت طراحی شده است.چی یاد بگیریم؟داستان سرایی برای یوزر استوری و استوری برداصول تئوری طراحی کاربر محور(User Centered Design)اصول تئوری طراحی تجربه کاربری(User Experience Design)طراحی(Wireframe)استفاده از ابزارهای طراحی مثل:FigmaSketch Adobe XDBalsamiqInVision StudioAdob Creative Suiteاصول کاربردپذیری(usability)prototypingGoogle analytics</description>
                <category>فرهاد صادقی</category>
                <author>فرهاد صادقی</author>
                <pubDate>Sat, 01 Mar 2025 14:49:20 +0330</pubDate>
            </item>
                    <item>
                <title>آموزش سریع Regex یا Regular Expression</title>
                <link>https://virgool.io/@farhad.sadeghi/%D8%A2%D9%85%D9%88%D8%B2%D8%B4-%D8%B3%D8%B1%DB%8C%D8%B9-regex-%DB%8C%D8%A7-regular-expression-ckjlfzhucle6</link>
                <description>در دنیای برنامه نویسی و نرم افزار، Regex از جمله ابزارهایی است که هر برنامه نویسی دیر یا زود با آن روبرو میشود و باید استفاده از آن را یاد بگیرد. عبارات باقاعده یا Regular Expression ها یا بصورت خلاصه شده Regexها ابزارهایی قدرتمند برای تطابق الگو و جستجو در رشته ها هستند.عبارات باقاعده می توانند برای کارهایی مانند اعتبار سنجی ورودی ها (input validating)، جستجو به دنبال الگوهای مشخص و یا دستکاری کردن رشته های متنی استفاده شوند.در زیر آموزش و راهنمای پایه ای از regex بیان شده است تا به شما کمک کند آن را فرا بگیرید.1. Basic SyntaxLiterals: Characters that match themselves. For example, a matches the character &quot;a&quot;.Metacharacters: Special characters that have specific meanings:.: Matches any single character except newline.^: Asserts the start of a string.$: Asserts the end of a string.*: Matches 0 or more occurrences of the preceding element.+: Matches 1 or more occurrences of the preceding element.?: Matches 0 or 1 occurrence of the preceding element (makes it optional).\: Escapes a metacharacter to treat it as a literal.2. Character ClassesBasic Classes:\d: Matches any digit (equivalent to [0-9]).\D: Matches any non-digit character.\w: Matches any word character (alphanumeric + underscore, equivalent to [a-zA-Z0-9_]).\W: Matches any non-word character.\s: Matches any whitespace character (spaces, tabs, line breaks).\S: Matches any non-whitespace character.Custom Classes: You can define your own character classes using square brackets:[abc]: Matches either &quot;a&quot;, &quot;b&quot;, or &quot;c&quot;.[a-z]: Matches any lowercase letter.[0-9]: Matches any digit.3. QuantifiersQuantifiers specify how many times an element can occur:{n}: Exactly n occurrences.{n,}: At least n occurrences.{n,m}: Between n and m occurrences.4. Groups and RangesGrouping: Use parentheses () to group parts of a regex. This allows you to apply quantifiers to the entire group. Example: (abc)+ matches &quot;abc&quot;, &quot;abcabc&quot;, etc.Alternation: Use the pipe | to specify alternatives. Example: cat|dog matches either &quot;cat&quot; or &quot;dog&quot;.5. AnchorsStart and End: Use ^ to assert the start of a string and $ to assert the end. Example: ^Hello matches &quot;Hello&quot; at the start of a string.مثال:در اینجا چند نمونه عملی از الگوهای regex آورده شده است:Email Validation:^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$Phone Number (US):^\(\d{3}\) \d{3}-\d{4}$Date (YYYY-MM-DD):^\d{4}-\d{2}-\d{2}$Lookaroundبررسی اطراف (Lookaround) در عبارات باقاعده (Regex) ابزاری است برای بررسی وجود یا عدم وجود یک الگو قبل یا بعد از موقعیت فعلی، بدون اینکه آن بخش از متن در نتیجه نهایی گنجانده شود. این ابزارها به دو دسته اصلی تقسیم میشوند:Lookahead (بررسی جلو)Lookbehind (بررسی عقب)هر کدام از این دسته ها به دو نوع مثبت (Positive) و منفی (Negative) تقسیم میشوند.1. Positive Lookahead (?=...)هدف: بررسی میکند که بعد از موقعیت فعلی، الگوی مشخصی وجود داشته باشد.مثال:فرض کنید میخواهیم کلمه cat را فقط زمانی پیدا کنیم که بعد از آن کلمه fish بیاید:cat(?= fish)تست:I have a cat fish → cat is foundI have a cat dog → cat can not be found2. Negative Lookahead (?!...)هدف: بررسی میکند که بعد از موقعیت فعلی، الگوی مشخصی وجود نداشته باشد.مثال:کلمه cat را پیدا کنید که بعد از آن کلمه dog نیاید:cat(?! dog)تست:I have a cat fish → cat is foundI have a cat dog → cat can not be found3. Positive Lookbehind (?&lt;=...)هدف: بررسی میکند که قبل از موقعیت فعلی، الگوی مشخصی وجود داشته باشد.مثال:اعدادی را پیدا کنید که قبل از آن علامت $ باشد:(?&lt;=\$)\d+تست:Price: $100 → 100 is foundPrice: €100 → 100 can not be found4. Negative Lookbehind (?&lt;!...)هدف: بررسی میکند که قبل از موقعیت فعلی، الگوی مشخصی وجود نداشته باشد.مثال:اعدادی را پیدا کنید که قبل از آن علامت $ نباشد:(?&lt;!\$)\d+تست:Price: €100 → 100 is foundPrice: $100 → 100 is not be foundمثال کاربردی ترکیبی (رمز عبور):فرض کنید میخواهیم رمز عبوری را اعتبارسنجی کنیم که:حداقل یک حرف بزرگ ([A-Z]) داشته باشد.حداقل یک عدد (\d) داشته باشد.حداقل ۸ کاراکتر طول داشته باشد.^(?=.*[A-Z])(?=.*\d).{8,}$توضیح:(?=.*[A-Z]) وجود حرف بزرگ در هر جای رشته.(?=.*\d) وجود عدد در هر جای رشته.. هر کاراکتری.{8,} حداقل ۸ کاراکتر.نکات مهم:بررسی اطراف (Lookaround) کاراکترها را مصرف نمیکند (Zero-width assertions).در Lookbehindها، الگو باید طول ثابتی داشته باشد (در برخی موتورهای Regex).برای ترکیب چند شرط، از چند Lookaround پشت سر هم استفاده کنید.Modifiersدر عبارات منظم &quot;modifier&quot; ها (یا &quot;flag&quot;ها) به شما این امکان را می‌دهند که رفتار جستجو را تغییر دهید. این modifier ها می‌توانند به شما کمک کنند تا جستجوهای خود را دقیق‌تر و کارآمدتر انجام دهید. در زیر به برخی از مهم‌ترین modifiers در regex اشاره می‌کنم:i (case insensitive) این modifier باعث می‌شود که جستجو به صورت غیر حساس به حروف بزرگ و کوچک انجام شود. به عنوان مثال می‌تواند abc، Abc، aBc و غیره را پیدا کند.m (multiline) با استفاده از این modifier، علامت ^ و $ به ابتدای هر خط و انتهای هر خط در یک متن چند خطی اشاره می‌کنند. به طور پیش‌فرض، این علامت‌ها فقط به ابتدا و انتهای کل متن اشاره دارند.s (dotall) این modifier باعث می‌شود که علامت . بتواند شامل کاراکترهای جدید (newline) نیز باشد. به طور پیش‌فرض، . فقط کاراکترهای غیر از newline را شامل می‌شود.x (extended) این modifier به شما این امکان را می‌دهد که از فضاهای خالی و کامنت‌ها در عبارات منظم استفاده کنید. با استفاده از این modifier، می‌توانید عبارات خود را خواناتر کنید.u (unicode) این modifier به شما این امکان را می‌دهد که از کاراکترهای یونیکد در عبارات منظم استفاده کنید.g (global)این modifier در برخی زبان‌ها (مانند JavaScript) به شما این امکان را می‌دهد که تمام تطابق‌ها را در یک متن پیدا کنید، نه فقط اولین تطابق را. (do not return after first match)مثال‌ها:برای جستجوی کلمه hello به صورت غیر حساس به حروف بزرگ و کوچک:(?i)helloبرای جستجوی یک الگو در یک متن چند خطی:(?m)^start.*end$برای جستجوی یک الگو که شامل newline باشد:(?s)hello.worldبا استفاده modifierها، می‌توانید عبارات منظم خود را به گونه‌ای تنظیم کنید که به نیازهای خاص شما پاسخ دهند.ابزارهای تمرین و تست Regexبرای انجام تمرین و تست از ابزارهای آنلاین زیر می توانید استفاده کنید:Regex101RegExrاین ابزارها الگوهای regex شما را توضیح می دهند و به شما امکان تست کردن الگوهای خود در مقابل ورودی ها (رشته های) ساده را فراهم می کنند.بهترین راه برای یادگیری regex تمرین کردن است. سعی کنید برای سناریوهای مختلف از جمله اعتبارسنجی نام کاربری، رمز عبور یا فرمت های خاص ورودی regex ایجاد نمایید.عبارات منظم می توانند پیچیده باشند اما با تمرین شما می توانید در استفاده از آنها خبره و مسلط باشید. از الگوهای ساده شروع کنید و به تدریج به سمت الگوهای پیچیده بروید.</description>
                <category>فرهاد صادقی</category>
                <author>فرهاد صادقی</author>
                <pubDate>Mon, 24 Feb 2025 14:54:38 +0330</pubDate>
            </item>
                    <item>
                <title>نقش‌های کلیدی در یک تیم توسعه نرم‌افزار کدامند؟</title>
                <link>https://virgool.io/@farhad.sadeghi/%D9%86%D9%82%D8%B4-%D9%87%D8%A7%DB%8C-%DA%A9%D9%84%DB%8C%D8%AF%DB%8C-%D8%AF%D8%B1-%DB%8C%DA%A9-%D8%AA%DB%8C%D9%85-%D8%AA%D9%88%D8%B3%D8%B9%D9%87-%D9%86%D8%B1%D9%85-%D8%A7%D9%81%D8%B2%D8%A7%D8%B1-%DA%A9%D8%AF%D8%A7%D9%85%D9%86%D8%AF-k3aiizq0dahh</link>
                <description>مالک محصول (PO)Product Ownerمدیر پروژه (PM)Project managerتحلیل‌گر کسب و کار (BA)Business Analystتحلیل‌گر سیستم (SA)System Analystطراح UI/UX یا طراح نرم‌افزار (SD)کشف ایده (اثبات مفهوم برنامه با ایجاد صفحه نمایش برنامه)نمونه‌سازی یا پروتوتایپینگتست ایده هویت برند (طراحی لوگو و سایر عناصر بصری)رابط کاربری و تجربه کاربریمهندس نرم‌افزار (SE)مهندسان فرانت‌اندمهندسان بک‌اندمهندسان موبایلمهندسان پایگاه دادهمعمار نرم‌افزار (SA) (Software Architect)معمار نرم‌افزار ماهرترین مهندس تیم است. بر خلاف سایر متخصصان نرم‌افزار، معمار نرم‌افزار نه تنها کدنویسی کرده و روی توسعه اپلیکیشن کار می‌کند، بلکه به مدیریت پروژه و تجزیه و تحلیل سیستم کمک می‌کند و ارتباط اساسی بین جنبه‌های کسب و کار و فنی تیم را فراهم می‌سازد.مهندس تست یا مهندس تضمین کیفیت (TE یا QA)Software Test EngineerSoftware Quality Assurance</description>
                <category>فرهاد صادقی</category>
                <author>فرهاد صادقی</author>
                <pubDate>Thu, 06 Feb 2025 16:43:06 +0330</pubDate>
            </item>
                    <item>
                <title>در C# چطور کنترلر WebAPI پس از برگرداندن جواب به کلاینت، به پردازش ادامه دهد</title>
                <link>https://virgool.io/@farhad.sadeghi/%D8%AF%D8%B1-c-%DA%86%D8%B7%D9%88%D8%B1-%DA%A9%D9%86%D8%AA%D8%B1%D9%84%D8%B1-webapi-%D9%BE%D8%B3-%D8%A7%D8%B2-%D8%A8%D8%B1%DA%AF%D8%B1%D8%AF%D8%A7%D9%86%D8%AF%D9%86-%D8%AC%D9%88%D8%A7%D8%A8-%D8%A8%D9%87-%DA%A9%D9%84%D8%A7%DB%8C%D9%86%D8%AA%D8%AA-%D8%A8%D9%87-%D9%BE%D8%B1%D8%AF%D8%A7%D8%B2%D8%B4-%D8%A7%D8%AF%D8%A7%D9%85%D9%87-%D8%AF%D9%87%D8%AF-hrbijoh1vvx3</link>
                <description>آیا در C# تا به حال به یک راه حل &quot;fire and forget&quot; نیاز داشته اید که در آن مشتری یک کنترلر  WebAPI را فراخوانی کند که کاری طولانی مدت انجام می دهد، اما واقعاً نتیجه فراخوانی اهمیتی برای مشتری ندارد؟به عنوان مثال، فرض کنید یک job زمانبندی شده دارید که یک سری وظایف را اجرا می کند و یکی از آنها فراخوانی یک WebAPI برای ایجاد چیزی شبیه انتقال داده از جدول SQL Server به یک فایل است.مشکلجدول بزرگ است و انتقال آن، job زمانبندی شده را از اجرای بقیه وظایف در فرآیند باز می‌دارد، یا فرآیند زمان‌بندی  را متوقف می‌کند یا با خطای Timeout مواجه می شود. در حالی که نتیجه وب سرویس هیچ اهمیتی در نتیجه نهایی فرآیند ندارد، زیرا WebAPI، خطاها را به روش دیگری مانند ایمیل گزارش می دهد.راه حلباید WebAPI یک کد HttpStatus مانند 200 OK در جواب ارسال کند و بگوید که درخواست مشتری به دست من رسید و فرآیند درخواست کامل شده است، در حالی که همچنان به کار روی درخواست در پس‌زمینه ادامه می‌دهد.برای افزودن قابلیت fire and forget، در کنترلر WebAPI خود، این کار را انجام دهید:public async Task&lt;IActionResult&gt; Post(string id)
{
    try
    {
        return Ok(&#039;Request submitted successfully&#039;);
    }
    finally
    {
        Response.OnCompleted(async () =&gt;
        {
            await DoProcessing(id);
        });
    }
} بخش کلیدی کد قسمت Response.OnCompleted است که به برنامه شما اجازه می دهد حتی پس از گزارش OK به مشتری، به اجرای خود ادامه دهد.</description>
                <category>فرهاد صادقی</category>
                <author>فرهاد صادقی</author>
                <pubDate>Sat, 11 Jan 2025 15:05:10 +0330</pubDate>
            </item>
                    <item>
                <title>مدیریت جریان ارزش و DevOps 2.0</title>
                <link>https://virgool.io/@farhad.sadeghi/%D9%85%D8%AF%DB%8C%D8%B1%DB%8C%D8%AA-%D8%AC%D8%B1%DB%8C%D8%A7%D9%86-%D8%A7%D8%B1%D8%B2%D8%B4-%D9%88-devops-20-lhfwksobapuo</link>
                <description>فلسفه مدیریت جریان ارزش (Value Stream Management) چندان جدید نیست، اما با تشکیل کنسرسیوم VSM، که VSM را به عنوان &quot;نسل بعدی DevOps&quot; معرفی می کند، اعتبار عمومی یافت. تشکیل دهندگان این کنسرسیوم می گویند که اگرچه اصول DevOps باعث ایجاد سازمانهایی با عملکرد بالاتر می شود، اما دشوار است  وقتی سازمانهای شما از انباره های اطلاعات ساخته می شوند و داده ها دفن می شوند، چیزی بهبود یابد. تفکر و کار به عنوان جریان های ارزشی به معنای وسواس تیمها در مورد ارزشی است کار آنها برای مشتری ایجاد می کند.موسسه پژوهشی گارتنر همچنین در مورد VSM حرف های زیادی برای گفتن دارد. گارتنر پیش بینی می کند که طی دو سال آینده، 70٪ سازمان ها از مدیریت جریان ارزش برای بهبود جریان در روند DevOps استفاده می کنند و این امر آینده DevOps را تعریف می کند.بنابراین، آیا می توان تیم های چابک و DevOps را تشویق و ترغیب کرد تا گامی رو به جلو بردارند و درباره ارزشی که کار آنها برای مشتری ایجاد می کند وسواس داشته باشند؟ شکی نیست که مدیران و متخصصان فناوری اطلاعات، به صورت جداگانه، واقعاً می خواهند بهترین نرم افزارهای ممکن را ارائه دهند. اما وقتی پویایی سازمانی مانع این هدف شود، نرم افزارها از این هدف دور می شوند.اما VSM دقیقاً چیست؟ فلینت برنتون از چند سال قبل در یک پست فوربس شرح مفصلی در این مورد ارائه داده است. مدیریت جریان ارزش VSM یک عمل تجاری ناب است که به تعیین ارزش توسعه نرم افزار و تلاشها برای تحویل آن کمک می کند.این مفهوم همچنین به بهبود جریان ارزش سازمان کمک می کند، در حالی که چرخه عمر تحویل نرم افزار را کنترل می کند. با شناسایی و بررسی جریان ارزشها، به جای &quot;ویژگی ها و عملکردها&quot; و اندازه گیری موفقیت در تحویل نرم افزار، تیم ها می توانند انرژی و زمان بیشتری روی موضوعات مثمر ثمر و کارا به جای ناکارایی ها بگذارند.ممکن است سوال شود، آیا این همان هدفی نیست که توسعه نرم افزار چابک و DevOps قرار بود محقق کند؟ برنتون اظهار می دارد Agile ،DevOps و مدیریت جریان ارزش نیروهای مکمل یکدیگر هستند. نقش VSM با جمع آوری اندازه گیری ها و معیارهای مهم برای نتایج کسب و کار  یا&quot;نگاشت جریان ارزش&quot;، فراهم کردن قابلیت دید در کل چرخه عمر نرم افزار است.به گفته تحلیلگران گارتنر، برای تیم های Agile و DevOps تشخیص و از بین بردن محدودیت های تحویل محصول چالش برانگیز است. تیمهای Agile و DevOps که فقط معیارهای عملکرد فنی را در نظر می گیرند (به استثنای معیارهای مشتری مداری) نمی توانند اولویت های خود را با سازمان هماهنگ کنند. تأثیر روی شیوه هایی مانند VSM در ابتکارات تحول دیجیتال به طور بالقوه می تواند عمیق باشد.رهبران شرکت ها می خواهند درک بهتری از چگونگی کمک نرم افزار به پیشبرد اهداف سازمانی خود داشته باشند. یک نظرسنجی از 600 مدیر فناوری اطلاعات که به تازگی توسط Digital. ai، ارائه کننده راهکارهای VSM و عضو موسس کنسرسیوم VSM منتشر شده، نشان می دهد که چه میزان تغییر شکل دیجیتال به یک نگرانی سطح بالای تجاری و سازمانی تبدیل شده است.94٪ از پاسخ دهندگان موافقت کردند که باید توسعه و تحویل نرم افزار خود را به اهداف تجاری نزدیک کنند، اما تنها 54٪ گفتند که تیم های تجاری، IT و امنیتی آنها از نظر استراتژیک همسو هستند و در راستای اهداف مشابه کار می کنند.نود و پنج درصد مدیران معتقدند که سازمان های آنها در حال حاضر به نوعی VSM را اجرا می کنند ولی تنها 50٪ سازمانهای خود را &quot;مشتری محور&quot; می دانند. گفتنی است، طراحان این نظرسنجی همچنین اشاره کردند، هیچ اتفاق نظر روشنی در مورد معنای VSM در شرکت های آنها وجود ندارد.تیم Gartner خاطرنشان می کند: نگاشت جریان ارزش تیم های DevOps را قادر می سازد از اتلاف و اصراف ممانعت به عمل آورند، اعتماد متقابل ایجاد کنند، شفافیت را افزایش دهند و اهداف خود را با اهداف سازمانی هماهنگ کنند. این رویکرد&quot;تفکر سیستمی&quot; به تیم های DevOps کمک می کند تا تمرکز خود را فراتر از معیارهای عملیاتی اعلام شده گسترش دهند. در عوض شاخص های عملکرد مشتری مدار و در سطح تیم را ارائه دهند.</description>
                <category>فرهاد صادقی</category>
                <author>فرهاد صادقی</author>
                <pubDate>Sat, 07 Dec 2024 19:25:32 +0330</pubDate>
            </item>
                    <item>
                <title>پیاده سازی تولید ناب و رسم جریان ارزش (VSM)</title>
                <link>https://virgool.io/@farhad.sadeghi/%D9%BE%DB%8C%D8%A7%D8%AF%D9%87-%D8%B3%D8%A7%D8%B2%DB%8C-%D8%AA%D9%88%D9%84%DB%8C%D8%AF-%D9%86%D8%A7%D8%A8-%D9%88-%D9%86%D9%82%D8%B4%D9%87-%D8%A8%D8%B1%D8%AF%D8%A7%D8%B1%DB%8C-%D8%AC%D8%B1%DB%8C%D8%A7%D9%86-%D8%A7%D8%B1%D8%B2%D8%B4-vsm-in3id8bx0btj</link>
                <description>تولید ناب اولین بار در سال های پایانی جنگ جهانی دوم و هم زمان با نیاز شدید ژاپن به وسایل نقلیه ی موتوری توسط تای چی اونو در شرکت تویوتا عنوان و سپس در سال 1990 به همت جیمز ووماک و همکاران وی از دانشگاه ام آی تی در قالب یک طرح تحقیقاتی مطرح و در کتابی به نام ماشینی که جهان را تغییر داد منتشر گشت. تولید ناب در واقع از مزایای تولید دستی و انبوه استفاده و از معایبی چون قیمت بالا و عدم تنوع محصول نهایی اجتناب می کند. زیرا به طور خلاصه در تولید دستی نیروی کار ماهر ، حجم پایین تولید و قیمت نهایی بالا مطرح است که حتی با افزایش میزان محصول هم کاهش محسوسی نخواهد داشت. در تولید انبوه نیز عمدتاً از ماشین آلات گران قیمت و کارگران غیر ماهر استفاده می شود که همین امر هرگونه نوآوری در خط تولید را به دلیل گران تر تمام شدن قطعه ی جدید عملاً غیر ممکن می سازد در نتیجه محصول نهایی به بهای از دست رفتن تنوع فقط ارزان تر به دست مشتری خواهد رسید. تای چی اونو مهندس شرکت تویوتا در دهه 1930 به آمریکا سفر و از شرکت اتوموبیل سازی فورد بازدید نمود ولی به این نتیجه رسید که سیستم تولید انبوه آن ها پر از انواع اتلاف است. هفت اتلاف مد نظر وی به شرح زیر می باشند:تولید بیش از تقاضاموجودی بالا در انبارزمان های تاخیرحمل و نقل های غیر ضروریپردازش زیاد محصولات به دلیل طراحی اولیه ضعیفحرکات زائد کارگران که ارزش افزوده ای به بار نمی آوردتولیدات معیوب که باعث دوباره کاری یا از دست دادن سهم بازار می شونداصول اصلی تفکر تولید ناب نیز از قرار زیر است:جلوگیری از تولید محصولات معیوبتوجه به نیازهای واقعی مشتریانپیاده کردن اصول کایزن در کارخانهگسترش ارتباطات درون مجموعهنقشه برداری جریان ارزش اولین گام در جهت پیاده سازی تولید ناب (lean Production)رسم جریان ارزش (VSM) که در ابتدا، نقشه جریان مواد و اطلاعات نامیده می شد، یک دیاگرام تک صفحه اي است که در آن فرآیند استفاده شده براي تولید یک محصول اعم از جریان حرکت مواد از مرحله تأمین مواد اولیه تا در اختیار گرفتن محصول نهایی توسط مشتري، نمایش داده می شود. این دیاگرام براي اولین بار توسط بخش مشاوره مدیریت عملیات شرکت خودروسازي تویوتا در اواخر دهه 1980 ابداع شد.همانطور که برای ساختن یک بنا احتیاج به نقشه ساخت داریم جهت پیاده سازی سیستم تولید ناب نیز احتیاج به یک نقشه راهنما داریم. نقشه ای که در سیستم تولید ناب بعنوان راهنما از آن استفاده می گردد نقشه جریان ارزش Value-stream mapping نام دارد. بر خلاف تصور، این نقشه همانند یک نقشه layout کارخانه نمیباشد و تمرکز ما در این نقشه بروی مشخص کردن اعمالی است که از دید مشتری ارزش آفرین و یا فاقد ارزش میباشد. در این نقشه گرافیکی که با علایم ساده و قابل فهم ترسیم میشود میتوان حرکت مواد و اطلاعات از در ورود تا در خروج کارخانه را نشان داد. جهت رسم این نقشه باید کاغذ و مدادی تدارک ببینید و شخصا در کارگاه حضور یابید تا با پیمایش مراحل تولید بتوانید به درک درستی از حرکت و توالی فرآیندها دست یابید. توصیه میشود جهت رسم نقشه جریان ارزش معکوس عمل نمایید و از قسمت ارسال محصول نهایی شروع کنید و از قسمت های مختلف عبور کنید تا به بخش دریافت مواد اولیه برسید. در طی این پیمایش مسیر می بایست اطلاعاتی را از ایستگاه های کاری جمع آوری نمایید. بهتر است این اطلاعات شامل :زمان چرخه محصول ( cycle time ) که نشان دهنده زمانی است که یک قطعه از فرآیندی خارج میشودزمان تبدیل ( change overtime) که بیانگر زمان جابجایی تولید یک نوع محصول به تولید نوع دیگر می باشدزمان قابل استفاده بودن ماشین آلاتاندازه دسته های تولیدتعداد اپراتورزمان مفید کاریمیزان نرخ ضایعات و غیرهبیاد داشته باشید تمامی اطلاعات مورد نیاز را شخصا محاسبه نمایید و از داده های قبلی کارگاه استفاده نکنید، همچنین در زمان پیمایش فرآیندها از یک کرنومتر استفاده کرده و تمامی زمان ها را برحسب ثانیه محاسبه نمایید. بطور کل هدف از نقشه برداری جریان ارزش شناسایی منابع و ریشه های اتلاف و حذف آن ها از طریق پیاده سازی وضع آینده میباشد. پس از ترسیم نقشه جریان ارزش حال نوبت رسم نقشه وضع آینده است. برای اینکه بتوانید نقشه وضع آینده را تهیه کنید خیلی خوب است که در جستجوی یافتن پاسخ پرسش های ذیل باشید:بر اساس زمان کار فرآیند پایین جریانی که از همه به مشتری نزدیک تر است، زمان تکت شما چیست؟آیا باید محصول را نخست به سوپرمارکت محصول نهایی بفرستید که تحت کشش مشتری کار میکند یا مستقیما محصول را برای مشتری ارسال کنید؟در کدام نقطه از جریان ارزش میتوانید محصول را در یک حرکت پیوسته پردازش کنید؟برای کنترل تولید فرآیندهای بالای جریان باید در چه نقاطی از سیستم کشش سوپرمارکتی استفاده کنید؟در کدام نقطه از زنجیره تولید میتوانید تولید را زمان بندی کنید؟چگونه میتوانید در فرآیند سرعت ساز ، ترکیب تولید را هموار کنید؟در فرآیند سرعت ساز باید بطور ثابت، چه حجمی از کار را وارد و خارج کنید؟کدام بهبود های فرآیندی لازم هستند تا بتوانید در جریان ارزش حرکتی را ایجاد کنید که در طراحی وضع آینده تعیین نموده اید؟براساس پاسخ هایی که به این پرسش ها میدهید، ایده های مربوط به وضع آینده را بروی نقشه وضع موجود مشخص کنید. مهمترین نکته در خصوص برنامه تحقق وضع آینده این است که فکر نکنید دارید مجموعه ای از تکنیک ها را پیاده میکنید، بلکه این برنامه را چونان فرآیند ایجاد مجموعه ای از حرکت های مرتبط با هم تصور کنید که برای یک خانواده محصول صورت میگیرد.نقشه جریان ارزش نشان می دهد که به کجا میخواهید بروید. با استفاده از نقشه وضع آینده ای که ترسیم میکنید می توانید برنامه سالانه جریان ارزش را تدوین نمایید، این برنامه شامل:برنامه دقیق و مرحله به مرحله انجام کارهایی معین در زمانی معیناهداف قابل برنامه ریزیمقاطع دقیق کنترل با ضرب الاجل های واقعی و نام مسئولین بازبینیبا استفاده از نکات فوق می توانید بروی نقشه وضع آینده حلقه هایی رسم نمایید جهت جداسازی قسمت های مختلف نقشه و مطابق با اولویت بندی این حلقه ها را شماره گذاری نمایید. یک استراتژی کارآمد و موثر آن است که کار پیاده سازی را با حلقه سرعت ساز پایین جریان شروع کنید و سپس به وقت ضرورت بطرف بالای جریان پیش بروید. حلقه سرعت ساز که نزدیک ترین حلقه به مشتری نهایی است برای شما به عنوان یک مشتری داخلی عمل خواهد کرد و تمامی تقاضاها را در حلقه های بالای جریان تحت کنترل خود در خواهد آورد. هنگامی که در حلقه سرعت ساز حرکت محصول ناب شد و ثبات یافت آنگاه مشکلات بالای جریان که نیاز به توجه دارند آشکار خواهد شد. بطور مشخص بهتر است برای انجام بهبودها در یک حلقه از الگو ذیل پیروی نمایید:ایجاد حرکت پیوسته مبتنی بر زمان تکتاستقرار یک سیستم کششی برای کنترل تولیدهموارسازیانجام کایزن برای حذف پیوسته اتلاف ها، کاهش اندازه دسته ها، کوچک کردن سوپرمارکت ها و وسعت بخشیدن به گستره حرکت پیوستهدر پایان باید خاطر نشان کرد که پیاده سازی تولید ناب انجام یک کار گروهی است که تمامی افراد از مدیران ارشد تا کارگران ساده درگیر این سیستم میشوند و تنها در سایه همکاری، همدلی و پشتکار فراوان است که قادر خواهید بود تولید ناب را پیاده سازی کنید. جهت دستیابی به اهداف نقشه وضع آینده باید مدیر جریان ارزش تعیین شود که وظیفه اش رهبری افرادی است که فرآیند را اجرا میکنند، مدیر جریان ارزش مسئولیت هزینه و کیفیت محصول را در وضع حاضر و ترسیم نقشه وضع آینده و تحقق آن را به رهبری خود بر عهده خواهد داشت. آنچه در این نوشته آمده است مقدمه ای مختصر جهت آشنایی با نقشه جریان ارزش می باشد، علاقمندان میتوانند جهت آموزش و بررسی کامل نقشه جریان ارزش به کتاب مفید آموزش دیدن نوشته مایک رادر و جان شوک مراجعه نمایند.کاربردهای نقشه جریان ارزشالبته VSM منافع زیادي به دنبال دارد که از آن جمله می توان به موارد زیر اشاره کرد :نه تنها بهترین ابزار براي شناسایی تلفات است، بلکه از آن براي شناسایی ریشه هاي بروز تلفات نیز استفاده می شود.به افراد کمک می کند که به جاي ارتقاء و بهبود جزیرهاي فرایندها، سیستم را بهبود بخشند.یک زبان قابل فهم براي صحبت و تحلیل جمعی چگونگی عملکرد فرایند تولید است.این ابزار بر تحلیل وضعیت واقعی جریان مواد و اطلاعات استوار است.در این ابزار مفاهیم عمیق تولید ناب با ابزار تولید ناب به خوبی ادغام شده است.علاوه بر نمایش جریان کار و اطلاعات، حسن دیگري دارد و آن آشکارسازي تلفات زمانی با نمایش زمان صرف شده در هر فرآیند خط تولید در مقایسه با کل زمان تلف شده از مرحله سفارش تا تحویل کالا به مشتري است. چرا که اغلب تلفات منابعی نظیر مواد، تجهیزات و فضا به راحتی قابل تشخیص است، ولی تلفات زمانی در پشت فعالیتها و رفت و آمدهاي غیرضروري پوشیده و مخفی است.از دیدگاه تولید ناب هشت قلم ضایعات (از نگاه سیستم تولید تویوتا) را میتوان مطرح کرد که در ادامه خواهیم خواند:حمل و نقل هایی که باوجود غیرضروری بودن انجام می شوندموجودی هایی که اضافی می باشندجابه‎جا کردن افراد و ماشین آلات یا تجهیزات درصورتی که ضروری نمی باشد.زمانی که برای انتظارافراد یا تجهیزات بیکار صرف می شوداینکه بیش از حد یک محصول را تولید کنیمپرداختن به محصول بصورتی که بیش از جد باشد و پرداختن به محصول بیشتر از آنچه که مشتری نیاز دارد بطور مثال پرداختن به طرحهایی که برای تولید آنها نیاز به تکنولوژی با لا و حتی غیر ضروری داریمنقص‎هایی که برای اصلاح انها هزینه و تلاش زیادی لازم استتلف شدن استعدادها و نوابغی که مورد استفاده قرار نمی گیرند.مورد هشتم ابتدا در سیستم تولید تویوتا قرار نداشت با اینحال بعضا این مورد را هم مطرح می کنند.</description>
                <category>فرهاد صادقی</category>
                <author>فرهاد صادقی</author>
                <pubDate>Wed, 04 Dec 2024 19:50:21 +0330</pubDate>
            </item>
                    <item>
                <title>اصول SOLID</title>
                <link>https://virgool.io/@farhad.sadeghi/%D8%A7%D8%B5%D9%88%D9%84-solid-naztdpgggcse</link>
                <description>اصول SOLID یک اصول قانون مند در برنامه نویسی شی گرا هستند که  در تمام زبان های برنامه نویسی شی گرا  موجود و قابل پیاده سازی است .کلمه SOLID مخفف پنج اصل بسیار مهم در مدیریت وابستگی (Dependency Management) در توسعه ی برنامه های شی گرا می باشد. در واقع هر کدام از حروف کلمه ی SOLID به یکی از این اصول بر می گردد.یکی از مشکلاتی که طراحی نامناسب برنامه های شی گرا برای برنامه نویسان ایجاد می کند موضوع مدیریت وابستگی در اجزای برنامه می باشد. اگر این وابستگی به درستی مدیریت نشود مشکلاتی شبیه موارد زیر در برنامه ایجاد می شوند:برنامه ی نوشته شده را نمی توان تغییر داد و یا قابلیت جدید اضافه کرد. دلیل آن هم این است که با ایجاد تغییر در قسمتی از برنامه، این تغییر به صورت آبشاری در بقیه ی قسمت ها منتشر می شود و مجبور خواهیم بود که قسمت های زیادی از برنامه را تغییر دهیم. یعنی برنامه به یک برنامه ی ثابت و غیر قابل پیشرفت تبدیل می شود. (این مشکل را Rigidity می نامیم.)تغییر دادن برنامه مشکل است و آن هم به این دلیل که با ایجاد تغییر در یک قسمت از برنامه، قسمت های دیگر برنامه از کار می افتند و دچار مشکل می شوند. (این مشکل را Fragility می نامیم.)قابلیت استفاده مجدد از اجزای برنامه وجود ندارد. در واقع، قسمت های مجدد برنامه ی شی گرای شما آنچنان به هم وابستگی تو در تو دارند که به هیچ وجه نمی توانید یک قسمت را جدا کرده و در برنامه ی دیگری استفاده کنید. (این مشکل را Immobility می نامیم.)اصول SOLID که قصد رفع کردن این مشکلات و بسیاری مسائل گوناگون را دارد عبارت اند از:Single Responsibility PrincipleOpen-Closed PrincipleLiskov Substitution PrincipleInterface Segregation PrincipleDependency Inversion Principleبا کنار هم گذاشتن حرف اول هر کدام از این اصول کلمه ی SOLID ایجاد می شود. با در نظر گرفتن این پنج اصل و پیاده سازی آنها در برنامه های خود می توانید به یک طراحی شی گرای پاک و درست دست پیدا کنید.S - Single-responsibility Principle (اصلی تک مسئولیتی)Single-responsibility Principle (SRP) states:A class should have one and only one reason to change, meaning that a class should have only one job.نقل قول زیر توضیح رسمی هست که برای SRP ارائه شده:یک کلاس فقط باید به یک دلیل تغییر کنه.یعنی چی؟ 🤔این اصل به ما میگه که هر کلاسی که توی برنامه‌ی ما وجود داره، باید یک مسئولیت خاص و مشخص داشته باشه. در واقع این کلاس باید فقط و فقط مسئول یک عملکرد توی برنامه باشه.این جمله رو همه شنیدیم: یک کار انجام بده ولی درست انجام بده!O - Open-Closed Principle (اصل باز/بسته)Open-closed Principle (OCP) states:Objects or entities should be open for extension but closed for modification.تعریف رسمی این اصل به این صورت هست:موجودیت‌های یک نرم‌افزار (کلاس‌ها، ماژول‌ها، توابع و ...) باید برای توسعه داده شدن، باز و برای تغییر دادن، بسته باشند.توی این اصل از کلمه‌های باز و بسته استفاده شده. این کلمات با چیزی که توی ذهنمون داریم یکم متفاوت هست. اول بذارید معنی کلاس باز و بسته رو با هم بررسی کنیم و بعد به توضیح این اصل بپردازیم.چه زمانی به یک کلاس میگیم باز؟به کلاسی که بشه اون رو توسعه داد، بشه از اون extend کرد، متدها و پراپرتی‌های جدید اضافه کرد و ویژگی‌ها و رفتار اون رو تغییر داد، میگن باز.چه زمانی به یک کلاس میگیم بسته؟کلاسی که کامل باشه. یعنی 100% تست شده باشه که بتونه توسط بقیه کلاس‌ها استفاده بشه، پایدار باشه و در آینده تغییر نکنه، میگن بسته. توی بعضی از زبان‌های برنامه‌نویسی یکی از راه‌های بسته نگه داشتن یک کلاس، استفاده از کلمه کلیدی final هست.خب حالا بپردازیم به توضیح اصل OCP:اصل OCP میگه که ما باید کد رو جوری بنویسیم که وقتی می‌خوایم اون رو توسعه بدیم و ویژگی‌های جدید اضافه کنیم، مجبور نشیم اون رو تغییر بدیم و دستکاری کنیم. ویژگی‌های جدید باید براحتی و بدون دستکاری کردن قسمت‌های دیگه اضافه بشن.طبق این اصل کلاس باید همزمان هم بسته باشه و هم باز! یعنی همزمان که توسعه داده میشه (باز بودن)، تغییر نکنه و دستکاری نشه (بسته بودن).L - Liskov Substitution Principle (اصل جایگزینی لیسکوف)Liskov Substitution Principle states:Let q(x) be a property provable about objects of x of type T. Then q(y) should be provable for objects y of type S where S is a subtype of T.تعریف آکادمیک این اصل بصورت زیر هست:اگر S یک زیر کلاس از  T باشه، آبجکت‌های نوع T باید بتونن بدون تغییر دادن کد برنامه با آبجکت‌های نوع S جایگزین بشنپس باید در نظر داشته باشیم وقتی که میخواهیم یک کلاس رو با مشتق کردن توسعه بدیم، جاهایی از برنامه که از کلاس والد استفاده شده، باید بتونه بدون مشکل با کلاس‌های فرزند هم کار کنه. یعنی کلاس فرزند نباید ویژگی‌ها و رفتار کلاس والد رو تغییر بده. مثلا اگه کلاس والد یک متد داره که خروجی اون عددی هست، کلاس فرزند نباید این متد رو جوری رونوشت کنه که خروجی آرایه باشه.I - Interface Segregation Principle (اصل جداسازی اینترفیس‌ها)The interface segregation principle states:A client should never be forced to implement an interface that it doesn’t use, or clients shouldn’t be forced to depend on methods they do not use.توضیح رسمی و آکادمیک این اصل بصورت زیر هست:کلاس‌ها نباید مجبور باشن متدهایی که به اونها احتیاجی ندارن رو پیاده‌سازی کنناین اصل میگه که ما باید اینترفیس (Interface) ها رو جوری بنویسیم که وقتی یک کلاس از اون استفاده میکنه، مجبور نباشه متدهایی که لازم نداره رو پیاده‌سازی کنه. یعنی متدهای بی‌ربط نباید توی یک اینترفیس کنار هم باشن. در این مواقع باید اون اینترفیس، به دو یا چند اینترفیس دیگه شکسته بشه. این اصل شباهت زیادی به اصل اول SOLID داره که میگه کلاس‌ها باید فقط مسئول انجام یک کار باشن.رعایت کردن این اصل به ما کمک میکنه کدهای خواناتر و تمیزتری داشته باشیم. توی شی‌گرایی باید یک نکته رو درنظر داشته باشیم که هر چی از کلی‌نویسی (عمومی‌نویسی) دوری کنیم و کدهایی داشته باشیم که مجزا و تفکیک شده باشن، برنامه‌ای منسجم‌تر و ساختاریافته‌تر خواهیم داشت. بنابراین کدها قابل استفاده مجدد میشن، تست و Refactor هم راحت‌تر انجام میشه 👌D - Dependency Inversion Principle (اصل وارونگی وابستگی)Dependency inversion principle states:Entities must depend on abstractions, not on concretions. It states that the high-level module must not depend on the low-level module, but they should depend on abstractions.توضیح رسمی و آکادمیک این اصل به صورت زیر هست. این توضیح رو بخونید تا با هم ریز به ریز جزییاتش رو بررسی کنیم:کلاس‌های سطح بالا نباید به کلاس‌های سطح پایین وابسته باشن؛ هر دو باید وابسته به انتزاع (Abstractions) باشن. موارد انتزاعی نباید وابسته به جزییات باشن. جزییات باید وابسته به انتزاع باشنخب دوستان این توضیحی بود که خیلی آکادمیک و یکم گنگ هست. مواردی مثل کلاس سطح بالا و سطح پایین، انتزاع و جزییات مواردی هستن که باید روشن بشن تا بتونیم این اصل رو خوب درک کنیم.کلاس سطح پایین چیه؟ 🤔به کلاس‌هایی گفته میشه که مسئول عملیات اساسی و پایه‌ای توی نرم‌افزار هستن. مثل کلاسی که با دیتابیس یا هارددیسک ارتباط برقرار می‌کنه، کلاسی که برای ارسال ایمیل استفاده میشه و ...کلاس سطح بالا چیه؟ 🤔کلاس‌هایی که عملیات پیچیده‌تر و خاص‌تری انجام میدن و برای انجام این کار از کلاس‌های سطح پایین استفاده میکنن. برای مثال کلاس گزارش‌گیری برای ثبت و خوندن گزارش، به کلاس دیتابیس یا هارددیسک نیاز داره. کلاس Users، برای اطلاع‌رسانی به کاربرها به کلاس ایمیل نیاز داره.مفهوم انتزاع (Abstraction)کلاس‌های انتزاعی کلاس‌های هستن که قابل پیاده‌سازی نیستن اما به عنوان یک طرح و الگو برای کلاس‌های دیگه در نظر گرفته میشن. مثلا یک کلاس انتزاعی برای گربه، زرافه، پلنگ و پنگوئن، میشه کلاس Animal. خود Animal به خودی خود قابل پیاده‌سازی نیست. بلکه یک طرح کلی برای حیوونایی هستن که مثال زدیم. پس تک تک این حیوون‌ها یک ورژن کلی‌تر دارن که می‌تونیم اون رو Animal بنامیم.مفهوم جزییاتمنظور از جزییات توی تعریف این اصل، جزییات یک کلاس مثل نام و ویژگی پراپرتی‌ها و متدهاست.خب بپردازیم به بررسی این اصل. ابتدا کد زیر رو در نظر بگیرید:class MySql {
    public insert() {}
    public update() {}
    public delete() {}
}

class Log {
    private database: MySql;

    constructor() {
        this.database = new MySql;
    }
}فرض کنیم یک کلاس سطح پایین داریم مثلا دیتابیس MySql. و یک سری کلاس سطح بالا مثلاً گزارش‌گیری (Log) از این کلاس استفاده می‌کنه. اگه بخوایم یک تغییر توی کلاس دیتابیس انجام بدیم، ممکنه بطور مستقیم تاثیر بذاره روی کلاس‌هایی که ازش استفاده میکنن. مثلا اگه توی کلاس MySql اسم متد رو تغییر بدیم و یا پارامترها رو کم و زیاد کنیم، نهایتا توی کلاس Log این تغییرات رو باید اعمال کنیم.همچنین کلاس‌های سطح بالا قابل استفاده مجدد نیستن. مثلاً اگه بخوایم برای کلاس Log از دیتابیس‌های دیگه مثلا MongoDB یا هارددیسک استفاده کنیم باید کلاس Log رو تغییر بدیم یا یک کلاس جدا براساس هر نوع دیتابیس بسازیم.خب همونطور که می‌بینید اگه یک کلاس سطح بالا وابسته به یک کلاس سطح پایین باشه این مشکلات به وجود میاد.راه حلبرای حل این مشکل باید با اینترفیس، یک لایه انتزاعی درست کنیم. با این کار کلاس Log دیگه وابسته به یک کلاس خاص برای ذخیره‌سازی و خوندن اطلاعات نیست و می‌تونیم هر نوع دیتابیسی رو استفاده کنیم و برای کلاس Log اهمیتی نداره که با چه نوع دیتابیسی داره کار میکنه. چون وابسته به انتزاع هست.ابتدا یک اینترفیس میسازیم برای اینکه کلاس‌های سطح بالا و سطح پایین رو وابسته به این اینترفیس کنیم:interface Database {
    insert();
    update();
    delete();
}حالا کلاس‌های سطح پایین باید این اینترفیس رو پیاده‌سازی کنن تا وابسته به انتزاع بشن:class MySql implements Database {
    public insert() {}
    public update() {}
    public delete() {}
}

class FileSystem implements Database {
    public insert() {}
    public update() {}
    public delete() {}
}

class MongoDB implements Database {
    public insert() {}
    public update() {}
    public delete() {}
}و نهایتاً توی کلاس‌های سطح بالا، وابستگی به یک کلاس خاص رو به اینترفیس واگذار می‌کنیم. کلاس‌های سطح بالا زمانی وابسته به انتزاع میشن که بجای استفاده مستقیم از کلاس‌های سطح پایین، از یک اینترفیس (رابط) استفاده کنن:class Log {
    private db: Database;

    public setDatabase(db: Database) {
        this.db = db;
    }

    public update() {
        this.db.update();
    }
}همونطور که می‌بینیم وابستگی به یک کلاس خاص از بین رفت و میتونیم هر نوع دیتابیسی رو برای کلاس Log استفاده کنیم:logger = new Log;

logger.setDatabase(new MongoDB);
// ...
logger.setDatabase(new FileSystem);
// ...
logger.setDatabase(new MySql);

logger.update();</description>
                <category>فرهاد صادقی</category>
                <author>فرهاد صادقی</author>
                <pubDate>Wed, 27 Nov 2024 16:41:03 +0330</pubDate>
            </item>
                    <item>
                <title>کانفلوئنس (Confluence) چیست؟</title>
                <link>https://virgool.io/@farhad.sadeghi/%DA%A9%D8%A7%D9%86%D9%81%D9%84%D9%88%D8%A6%D9%86%D8%B3-confluence-%DA%86%DB%8C%D8%B3%D8%AA-lidctbwknzjk</link>
                <description>کانفلوئنس یک ابزار مدیریت مستندات و دانش است که کاملا تحت وب و به شکل ویکی (Wiki) است. این نرمافزار توسعه داده شده توسط شرکت اتلسین (Atlassian) است. ویژگیهایی مانند امکان نصب پلاگینهای متنوع، مدیریت دسترسی کامل، مدیریت نسخه، امکان ویرایش همزمان یک مستند، یکپارچه شدن با جیرا، کامنت گذاری روی مستند از جمله مهم ترین مزیتهای استفاده از این ابزار است.مشکلات مدیریت مستندات به شکل سنتیمدیریت مستندات در سازمانها از مهمترین دغدغه هایی است که سازمان از بدو شروع کار، با آن دست و پنجه نرم میکند. سازمانها همیشه به دنبال سامانه و سیستمهایی هستند که به کمک آن بتوانند مستندات جاری سازمان را به خوبی مدیریت کنند. یک سامانه مدیریت مستندات لازم است شامل ویژگی های زیر باشد: 1.  سهولت در نگهداری سامانه 2.  امکان دسته بندی مستندات به شکلهای مختلف 3.  مدیریت دسترسی افراد به مستندات 4.  سهولت دسترسیپذیری افرادنرم افزارهای مختلفی برای بحث مدیریت مستندات در سازمانهای مختلف مورد استفاده قرار میگیرند. یکی از معروفترین ابزارهای مورد استفاده در این زمینه Microsoft SharePoint است که یک Document Management System &#40;DMS&#41; است. سیستمهای DMS اساس کار خود را بر اساس فایلهای Word , Excel , PowerPoint و … قرار داده اند و هدف آنها ایجاد بستری برای دستهبندی، نگهداری و مدیریت دسترسی بر این فایلهاست.</description>
                <category>فرهاد صادقی</category>
                <author>فرهاد صادقی</author>
                <pubDate>Tue, 12 Nov 2024 20:30:23 +0330</pubDate>
            </item>
                    <item>
                <title>ورژن بندی معنایی (Semantic Versioning)</title>
                <link>https://virgool.io/@farhad.sadeghi/httpsvirgooliofarhad%D9%88%D8%B1%DA%98%D9%86-%D8%A8%D9%86%D8%AF%DB%8C-%D9%85%D8%B9%D9%86%D8%A7%DB%8C%DB%8C-semantic-versioning-w4vj8wxb2tg2-w4vj8wxb2tg2</link>
                <description>یکی از پر استفاده ترین نقشه های نسخه بندی، نسخه بندی معنایی می باشد. بر اساس وب سایت Semver این نسخه بندی به شکل زیر می باشد:شماره نسخه به حالت MAJOR.MINOR.PATCH و به صورت افزایشی، داده می شود:بروزرسانی شماره  Major :زمانی که توسعه دهندگان تغییرات مهمی را در یک API از محصول نرم اافزاری انجام می دهند، شماره اصلی(Major) را تغییر می دهند. این تغییر به این معنی است که تغییرات بزرگ بوده است، تا جایی که این نسخه را با نسخه های قبلی ناسازگار می کند. نرم افزار در این مرحله به شدت تکامل یافته است و بعید است با نسخه های قبلی کار کند. مثلا نسخه ۲.۱.۴ ممکن است با نسخه ۲.۲.۱ سازگار باشد ولی ممکن است دیگر با نسخه های ۳.۰.۰ به بالا سازگار نباشد.بروزرسانی شماره Minor:این شماره زمانی افزایش پیدا می کند که توسعه دهندگان ویژگی جدیدی را به نرم افزار اضافه می کنند که ورژن جدید همچنان با نسخه های قبلی با شماره Major یکسان سازگار می باشد. وقتی نسخه جدید به صورت minor ارائه می شود، آنها همچنان کاربرانی که بروزرسانی را انجام ندهند، پشتیبانی خواهند کرد. تغییرات در این نوع بروزرسانی ها برای کاربران ریسک پایینی دارد.شماره  Patch:برای تغییراتی که کارایی فعلی نرم افزار را تغییر نمی دهند، این شماره افزایش پیدا می کند. معمولا این شماره بعد از برطرف کردن باگ افزایش داده می شود.</description>
                <category>فرهاد صادقی</category>
                <author>فرهاد صادقی</author>
                <pubDate>Tue, 12 Nov 2024 19:12:27 +0330</pubDate>
            </item>
            </channel>
</rss>