سرنوشت Netflix در Spring Cloud و آینده آن

سلام. بعد از مقایسه سه مورد از Service Discovery های معروفی که در اسپرینگ کلود قابل استفاده است تصمیم گرفتم پست خاصی راجع به جایگزین Netflix به صورت کلی داشته باشم.

بی شک از زمانی که اسپرینگ کلود به صورت گسترده مورد استفاده قرار گرفت با نام بردن از آن ذهن ها سریعا به سمت کتابخانه های Netflix و راهکارهای آن از جمله Zuul, archaius, Eureka و Ribbon سوق پیدا می کرد. اما به تازگی در توضیحات آخرین انتشار Spring Cloud به وضوح آمده است که سه کتابخانه مهم شامل Zuul و Ribbon و Hystrix از کتابخانه Netflix حذف شده اند. هرچند در مستندات می توانید آن ها را پیدا کنید اما ظاهرا Spring Cloud تغییر مسیر داده که البته می توان از آن استقبال کرد. البته این تغییر پیش تر و در سال 2019 اعلام شده بود و اعلام شده بود که این کتابخانه ها به حالت maintenance خواهند رفت به این معنی که دیگر ویژگی به این کتابخانه ها اضافه نخواهد شد. اما همچنان کاربران زیادی به جهت پشتیبانی نسخه های بعدی از آن ها از جمله نسخه Hoxton از این کتابخانه ها همچنان این نسخه ها را برای توسعه انتخاب کرده اند. البته نا گفته نماند که با توجه به ارتقاء دشوار پروژه های در این سطح از یک نسخه به نسخه های بالاتر نمی توان این انتخاب را اشتباه دانست. همانطور که می دانید هر نسخه SpringCloud با نسخه مشخصی از Spring Boot سازگار است و ارتقاء نسخه ها کار ساده ای نخواهد بود.

همچنین از همان سال 2019 توسعه پایدار Ribbon و Hystrix از طرف Netflix بسیار کند شد و همچنین پروژه Atlas جایگزین پروژه Hystrix شد. اما با وجود اینکه پروژه zuul 2 توسط Netflix به صورت منبع باز منتشر شد مشخص نیست چرا Spring تصمیم گرفت آن را نیز کنار گزارد.

البته همچنان خبری راجع به Eureka وجود ندارد (شاید هم بنده اطلاعی نداشته باشم) اما به هرحال با توجه به اضافه شدن Consul و توسعه کند Eureka فکر میکنم جایگزین مناسب تری به وجود آمده و مقاله قبل مقایسه با دیگر ServiceDiscovery ها به همین علت انجام شد. البته در آن مقاله راجع به Alibaba Nacos و Kubernetes صحبتی نشد که به دلیل تمرکز بر کنسول که گزینه جالبی به نظر میرسید بود. نکته ای که باید به آن اشاره میشد این است که در واقع Kubernetes بر اساس etcd ساخته شده است و پشتیبانی از etcd نیز توسط Spring Cloud در حال توسعه است.

مدیریت تنظیمات

با حذف archaius از کتابخانه نتفلیکس در صورتی که از ServiceDiscovery غیر از کنسول استفاده می کنید مثلا Eureka می توانید از Spring Cloud Config به عنوان یک جایگزین با امکان پشتیبانی از Git, JDBC, Vault و یا فایل های ساده استفاده کنید. البته همانطور که اشاره شد کنسول را میتوان به عنوان کانفیگ سرور استفاده کرد. اما لازم است spring-cloud-starter-consul-config را به pom.xml خود اضافه نمایید.

سرور Gateway

جانشین Spring Cloud Netflix Zuul پروژه Cloud Spring Gateway است که عمری پنج ساله دارد و مورد استقبال قرار گرفته است. مانند Zuul 2 این api نیز از Netty به عنوان servlet container استفاده می کند و از routes, predicates و فیلتر پشتیبانی می کند. و با پشتیبانی مدیریت کانفیگ کنسول از تنظیمات آن قدرت مانور بیشتری نیز خواهید داشت. در زیر نمونه ای از این تنظیمات را مشاهده می کنید

spring:
   cloud:
      gateway:
         discovery:
            locator:
                enabled: true
        routes:
           - id: caller-service
             uri: lb://caller-service
             predicates:
                - Path=/caller/**
            filters:
               - RewritePath=/caller/(?.*), /$\{path}

گزینه جذاب دیگری که در کنار Cloud Spring Gateway در دسترس است KrakenD است که حدود چهار سال عمر دارد و با توجه به اینکه با زبان Go توسعه داده شده دارای سرعت قابل توجهی است که با توجه به ماهیت Gateway نباید از کنار آن ساده گذشت هرچند این ابزار برایمان زیاد آشنا به نظر نرسد اما قابلیت کارکرد آن از طریق DNS با کنسول در صورت استفاده می تواند تاثیر گذار باشد.

اما باید این مورد را لحاظ کرد که krakend از route های پیشرفته پشتیبانی نمی کند مثلا اگر route شبیه به /department/id داشته باشید نمی توان route دیگری مانند /department/id/employee داشت و باید از root تغییر کنند تا به تناقض برخورد نکنید.

ابزار LoadBalancer

در نهایت به یک ابزار مفید میرسیم که موافق و مخالفانی دارد و هرکدام استدلال خود را دارند. در نگاه به روز و جدیدتری شاهد توسعه spring cloud bus و توسعه روزافزون reactive هستیم و توصیه شده کمتر از فراخوانی به صورت rest بین سرویس های موجود در یک معماری مایکروسرویس استفاده شود. اما اگر بخواهیم با فرض اینکه این فراخوانی ها لازم است انجام شود و سرویس مورد نظر از نظر بار ممکن است چندین instance داشته باشد لازم است به فواید استفاده از Client side load balancing اشاره شود

به هر حال اگر از یک لود بالانس اصلی استفاده نمایید بر اثر fail شدن آن ارتباط سرویس ها قطع خواهد شد و این ریسک را می توان کاهش داد.

نکته مهم دیگر شامل: کاهش درخواست های اضافه در شبکه مربوط به لود بالانسر. کاهش ریسک ناشی از لزوم restart کردن لودبالانسر و کاهش هزینه دپلوی و کاهش پهنای باند اشغالی است.

در حال حاضر Spring Cloud Load Balancer جایگزین Ribbon شده است که با استفاده از انوتیشن LoadBalanced برسر بین RestTemplate یا WebClient خاصیت Client side load balancing را برای آن فعال کرد. البته هنوز ribbon به عنوان لودبالانسر پیش فرض spring انتخاب شده که اگر قصد دارید از Spring Cloud Load Balancer استفاده شود باید آن را غیر فعال کنید. با این روش به صورت خودکار سرویس با استفاده از service discovery لیست سرویس ها گرفته و به صورت راندرابین درخواست ارسال می کند که می توان آن را شخصی سازی نمود.