ميخائيل سالوسين. اجتماع جولانج. استخدام Go في الواجهة الخلفية لتطبيق Look+

ميخائيل سالوسين (المشار إليه فيما بعد باسم MS): - أهلاً بكم! اسمي ميخائيل. أنا أعمل كمطور خلفي في MC2 Software، وسأتحدث عن استخدام Go في الواجهة الخلفية لتطبيق الهاتف المحمول "Smotri+".

ميخائيل سالوسين. اجتماع جولانج. استخدام Go في الواجهة الخلفية لتطبيق Look+

هل يحب أحد هنا الهوكي؟

ميخائيل سالوسين. اجتماع جولانج. استخدام Go في الواجهة الخلفية لتطبيق Look+

إذا كان الأمر كذلك، فهذا التطبيق يناسبك. إنه مخصص لنظامي التشغيل Android و iOS ويُستخدم لمشاهدة بث الأحداث الرياضية المختلفة عبر الإنترنت وفي التسجيلات. ويحتوي التطبيق أيضًا على إحصائيات مختلفة، وبث نصي، وجداول حسب المؤتمرات، حسب البطولات، ومعلومات أخرى مفيدة للجماهير.

ميخائيل سالوسين. اجتماع جولانج. استخدام Go في الواجهة الخلفية لتطبيق Look+

يحتوي التطبيق أيضًا على ما يسمى بلحظات الفيديو، أي يمكنك مشاهدة اللحظات الأكثر إثارة في المباريات (الأهداف، المعارك، ركلات الترجيح، وما إلى ذلك). إذا كنت لا ترغب في مشاهدة البث بأكمله، يمكنك مشاهدة الأجزاء الأكثر إثارة للاهتمام فقط.

ما الذي تم استخدامه في التطوير؟

الجزء الرئيسي كتب بلغة جو. تمت كتابة واجهة برمجة التطبيقات التي يتواصل معها عملاء الهاتف المحمول بلغة Go. تمت أيضًا كتابة خدمة لإرسال الإشعارات الفورية إلى الهواتف المحمولة بلغة Go. كان علينا أيضًا أن نكتب ORM الخاص بنا، والذي قد نتحدث عنه يومًا ما. حسنًا، تمت كتابة بعض الخدمات الصغيرة بلغة Go: تغيير الحجم وتحميل الصور من جانب المحررين…

لقد استخدمنا PostgreSQL كقاعدة بيانات. تمت كتابة واجهة المحررين بلغة Ruby on Rails باستخدام أداة ActiveAdmin. تتم كتابة استيراد الإحصائيات من موفر الإحصائيات أيضًا بلغة Ruby.

لاختبارات API للنظام، استخدمنا unittest الخاص بـ Python. يتم استخدام Memcached لتقييد طلبات الدفع عبر واجهة برمجة التطبيقات، ويتم استخدام Chef للتحكم في التكوين، ويتم استخدام Zabbix لجمع إحصائيات النظام الداخلي ومراقبتها. Graylog2 مخصص لجمع السجلات، وSlate عبارة عن توثيق API للعملاء.

ميخائيل سالوسين. اجتماع جولانج. استخدام Go في الواجهة الخلفية لتطبيق Look+

اختيار البروتوكول

كانت المشكلة الأولى التي واجهتنا هي أنه كان علينا اختيار بروتوكول للتفاعل الخلفي مع عملاء الهاتف المحمول بناءً على النقاط التالية...

  • المتطلب الأهم هو أن يتم تحديث بيانات العملاء في الوقت الحقيقي. وهذا يعني أن كل من يشاهد البث حاليًا ينبغي أن يتلقى التحديثات على الفور تقريبًا.
  • من أجل التبسيط، افترضنا أن البيانات التي تتم مزامنتها مع العملاء لا يتم حذفها، بل يتم إخفاؤها باستخدام علامات خاصة.
  • يتم استلام جميع الطلبات النادرة (مثل الإحصائيات، وقوائم الفريق، وإحصائيات الفريق) عبر طلبات GET العادية.
  • بالإضافة إلى ذلك، كان على النظام أن يتعامل بسهولة مع 100 ألف مستخدم في وقت واحد.

وبناءً على ذلك، كان لدينا خياران للبروتوكول:

  1. مقابس الويب. لكننا لم نكن بحاجة إلى قنوات من العميل إلى الخادم. كنا بحاجة فقط إلى إرسال التحديثات من الخادم إلى العميل، لذا كان مقبس الويب ضروريًا.
  2. كانت الأحداث المرسلة عبر الخادم (SSE) هي الشيء الصحيح! إنه بسيط للغاية ويلبي، من حيث المبدأ، كل ما نحتاجه.

الأحداث المرسلة من الخادم

كلمات قليلة عن كيفية عمل هذا الشيء...

يعمل عبر اتصال http. يرسل العميل طلبًا، ويستجيب الخادم بـ Content-Type: text/event-stream ولا يغلق الاتصال مع العميل، ولكنه يستمر في كتابة البيانات إلى الاتصال:

ميخائيل سالوسين. اجتماع جولانج. استخدام Go في الواجهة الخلفية لتطبيق Look+

يمكن إرسال البيانات بالتنسيق المتفق عليه مع العملاء. في حالتنا، أرسلناها بهذا النموذج: أرسل حقل الحدث اسم الهيكل المتغير (الشخص، اللاعب)، وأرسل حقل البيانات JSON مع الحقول الجديدة المتغيرة للاعب.

والآن حول كيفية عمل التفاعل نفسه.

  • أول شيء يقوم به العميل هو تحديد متى تم إجراء آخر مزامنة مع الخدمة: ينظر إلى قاعدة البيانات المحلية الخاصة به ويحدد تاريخ آخر تغيير سجله.
  • يرسل طلب بهذا التاريخ.
  • وردًا على ذلك، نرسل له جميع التحديثات التي حدثت منذ ذلك التاريخ.
  • بعد ذلك يتصل بالقناة المباشرة ولا يغلقها إلا عند الحاجة لهذه التحديثات:

ميخائيل سالوسين. اجتماع جولانج. استخدام Go في الواجهة الخلفية لتطبيق Look+

نرسل له قائمة التغييرات: إذا سجل أحد هدفًا، نغير نتيجة المباراة؛ إذا أصيب شخص ما، فسيتم إرساله أيضًا في الوقت الفعلي. بهذه الطريقة، يتلقى العملاء على الفور بيانات محدثة في موجز أحداث المباراة. بشكل دوري، حتى يفهم العميل أن الخادم لم يمت، ولم يحدث له شيء، نرسل علامة زمنية كل 15 ثانية - حتى يعرف أن كل شيء على ما يرام وليس هناك حاجة لإعادة الاتصال.

كيف تتم خدمة الاتصال المباشر؟

  • أولاً، نقوم بإنشاء قناة ستستقبل التحديثات باستخدام المخزن المؤقت.
  • بعد ذلك نقوم بالاشتراك في هذه القناة لتلقي التحديثات.
  • لقد وضعنا العنوان الصحيح حتى يعرف العميل أن كل شيء على ما يرام.
  • إرسال أول إشارة ping. نقوم ببساطة بتسجيل طابع زمني للاتصال الحالي.
  • بعد ذلك نقوم بالقراءة من القناة بشكل متكرر حتى يتم إغلاق قناة التحديث. تتلقى القناة بشكل دوري إما الطابع الزمني الحالي أو التغييرات التي نكتبها بالفعل لفتح الاتصالات.

ميخائيل سالوسين. اجتماع جولانج. استخدام Go في الواجهة الخلفية لتطبيق Look+

كانت المشكلة الأولى التي واجهناها هي التالية: لكل اتصال مفتوح مع العميل، قمنا بإنشاء مؤقت يصدر صوتًا كل 15 ثانية - اتضح أنه إذا كان لدينا 6 آلاف اتصال مفتوحة لجهاز واحد (إلى خادم API واحد)، يتم إنشاء 6 آلاف مؤقت. وقد أدى هذا إلى عدم قدرة الماكينة على التعامل مع الحمل المطلوب. لم تكن المشكلة واضحة بالنسبة لنا، ولكننا حصلنا على القليل من المساعدة وقمنا بإصلاحها.

ونتيجة لذلك، أصبح الآن ping الخاص بنا يأتي من نفس القناة التي يأتي منها التحديث.

وبناءً على ذلك، يوجد مؤقت واحد فقط يصدر صوتًا كل 15 ثانية.

هناك العديد من الوظائف المساعدة هنا - إرسال الرأس، وping، والبنية نفسها. وهذا يعني أن اسم الجدول (الشخص، المباراة، الموسم) والمعلومات حول هذا السجل نفسه يتم نقلها هنا:

ميخائيل سالوسين. اجتماع جولانج. استخدام Go في الواجهة الخلفية لتطبيق Look+

آلية إرسال التحديثات

والآن القليل عن من أين تأتي التغييرات. لدينا العديد من الأشخاص، المحررين، الذين يشاهدون البث في الوقت الحقيقي. إنهم يخلقون جميع الأحداث: طرد شخص ما، إصابة شخص ما، نوع من التبديل...

بمساعدة CMS، يتم إدخال البيانات إلى قاعدة البيانات. بعد ذلك، تقوم قاعدة البيانات بإخطار خوادم API بهذا الأمر باستخدام آلية الاستماع/الإخطار. تقوم خوادم API بالفعل بإرسال هذه المعلومات إلى العملاء. وبالتالي، لدينا أساسًا عدد قليل من الخوادم المتصلة بقاعدة البيانات ولا يوجد حمل معين على قاعدة البيانات، لأن العميل لا يتفاعل مباشرة مع قاعدة البيانات بأي شكل من الأشكال:

ميخائيل سالوسين. اجتماع جولانج. استخدام Go في الواجهة الخلفية لتطبيق Look+

PostgreSQL: الاستماع/الإخطار

تتيح لك آلية الاستماع/الإخطار في Postgres إخطار المشتركين في الحدث بأن بعض الأحداث قد تغيرت - تم إنشاء بعض السجلات في قاعدة البيانات. ولتحقيق هذه الغاية، كتبنا مشغلًا ووظيفة بسيطة:

ميخائيل سالوسين. اجتماع جولانج. استخدام Go في الواجهة الخلفية لتطبيق Look+

عند إدراج سجل أو تغييره، نقوم باستدعاء وظيفة الإشعار على قناة data_updates، ونمرر إليها اسم الجدول ومعرف السجل الذي تم تغييره أو إدراجه.

بالنسبة لجميع الجداول التي تحتاج إلى المزامنة مع العميل، نقوم بتعريف مشغل يقوم، بعد تغيير/تحديث سجل، باستدعاء الوظيفة المحددة في الشريحة أدناه.
كيف تشترك واجهة برمجة التطبيقات (API) في هذه التغييرات؟

يتم إنشاء آلية Fanout - حيث تقوم بإرسال رسائل إلى العميل. يقوم بجمع جميع قنوات العملاء ويرسل التحديثات التي تلقاها من خلال هذه القنوات:

ميخائيل سالوسين. اجتماع جولانج. استخدام Go في الواجهة الخلفية لتطبيق Look+

هذه هي مكتبة pq القياسية، التي تتصل بقاعدة البيانات وتقول إنها تريد الاستماع إلى القناة (data_updates)، وتتحقق من أن الاتصال مفتوح وأن كل شيء على ما يرام. أتجاهل التحقق من الأخطاء لتوفير المساحة (عدم التحقق أمر خطير).

بعد ذلك، قمنا بتعيين Ticker بشكل غير متزامن، والذي سيرسل إشارة ping كل 15 ثانية، والبدء في الاستماع إلى القناة التي اشتركنا فيها. إذا تلقينا إشارة ping، فإننا ننشر تلك الإشارة. إذا تلقينا منشورًا، فسوف ننشره لجميع المشتركين في هذه المجموعة.

كيف يعمل Fan-out؟

في اللغة الروسية تُترجم إلى "المقسم". لدينا كائن واحد يسجل المشتركين الذين يريدون تلقي بعض التحديثات. وبمجرد وصول تحديث لهذا الكائن، فإنه يقوم بتوزيع هذا التحديث على جميع المشتركين لديه. بسيط جداً:

ميخائيل سالوسين. اجتماع جولانج. استخدام Go في الواجهة الخلفية لتطبيق Look+

كيف يتم تنفيذه في Go:

ميخائيل سالوسين. اجتماع جولانج. استخدام Go في الواجهة الخلفية لتطبيق Look+

هناك بنية، يتم مزامنتها باستخدام Mutexes. يحتوي على حقل يخزن حالة اتصال Fanout بقاعدة البيانات، أي أنه يستمع حاليًا وسيستقبل التحديثات، بالإضافة إلى قائمة بجميع القنوات المتاحة - خريطة، مفتاحها هو القناة وهيكل في شكل قيم (في الواقع، لا يتم استخدامه بأي شكل من الأشكال).

طريقتان - متصل ومنفصل - تسمحان لنا بإخبار Fanout بأن لدينا اتصالاً بقاعدة البيانات، وقد ظهر، وأن الاتصال بقاعدة البيانات قد انقطع. في الحالة الثانية، عليك فصل جميع العملاء وإخبارهم بأنهم لم يعد بإمكانهم الاستماع إلى أي شيء وأن عليهم إعادة الاتصال لأن الاتصال معهم قد تم إغلاقه.

هناك أيضًا طريقة الاشتراك التي تضيف قناة إلى "المستمعين":

ميخائيل سالوسين. اجتماع جولانج. استخدام Go في الواجهة الخلفية لتطبيق Look+

هناك طريقة إلغاء الاشتراك، والتي تزيل القناة من المستمعين إذا انقطع اتصال العميل، وطريقة النشر، والتي تسمح لك بإرسال رسالة إلى جميع المشتركين.

السؤال: - ماذا ينتقل عبر هذه القناة؟

السيدة: - النموذج الذي تغير أو تم إرسال ping (في الأساس مجرد رقم أو عدد صحيح).

السيدة: - يمكنك إرسال أي شيء، أي هيكل، ونشره - يتحول فقط إلى JSON وهذا كل شيء.

السيدة: – نتلقى إشعارًا من Postgres – يحتوي على اسم الجدول والمعرف. من خلال اسم الجدول نحصل ومن خلال المعرف نحصل على السجل الذي نحتاجه، ونرسل هذا الهيكل للنشر.

بنية التحتية

كيف يبدو هذا من منظور البنية التحتية؟ لدينا 7 خوادم أجهزة: واحد منها مخصص بالكامل لقاعدة البيانات، والستة الأخرى تعمل على تشغيل الآلات الافتراضية. هناك 6 نسخ من واجهة برمجة التطبيقات (API): يتم تشغيل كل جهاز افتراضي يحتوي على واجهة برمجة التطبيقات (API) على خادم أجهزة منفصل - وهذا من أجل الموثوقية.

ميخائيل سالوسين. اجتماع جولانج. استخدام Go في الواجهة الخلفية لتطبيق Look+

لدينا واجهتان أماميتان تعملان بنظام Keepalived لتحسين إمكانية الوصول، بحيث يمكن لواجهة أمامية واحدة استبدال الأخرى إذا لزم الأمر. بالإضافة إلى نسختين من CMS.

هناك أيضًا مستورد للإحصائيات. هناك قاعدة بيانات تابعة يتم من خلالها إجراء نسخ احتياطية بشكل دوري. هناك Pigeon Pusher - التطبيق الذي يرسل الدفعات إلى العملاء، بالإضافة إلى أشياء البنية التحتية: Zabbix، وGraylog2، وChef.

في الواقع، هذه البنية التحتية زائدة عن الحاجة، لأنه من الممكن تقديم الخدمة لـ 100 ألف شخص باستخدام عدد أقل من الخوادم. لكن كان هناك أجهزة - استخدمناها (قيل لنا أن ذلك ممكن - لماذا لا).

إيجابيات لعبة جو

بعد العمل على هذا التطبيق، أصبحت هذه المزايا الواضحة لـ Go واضحة.

  • مكتبة http رائعة. بمساعدتها يمكنك إنشاء الكثير من الأشياء "خارج الصندوق".
  • بالإضافة إلى القنوات التي سمحت لنا بتنفيذ آلية لإرسال الإشعارات إلى العملاء بسهولة بالغة.
  • يعد كاشف السباق شيئًا رائعًا سمح لنا بإصلاح العديد من الأخطاء الحرجة (البنية الأساسية المرحلية). يتم تشغيل كل ما يعمل على التدريج وتجميعه باستخدام مفتاح Race؛ وبناءً على ذلك، يمكننا إلقاء نظرة على البنية التحتية للمسرح لمعرفة المشكلات المحتملة التي نواجهها.
  • التقليلية وبساطة اللغة.

ميخائيل سالوسين. اجتماع جولانج. استخدام Go في الواجهة الخلفية لتطبيق Look+

نحن نبحث عن المطورين! إذا أراد أي شخص ذلك، يرجى القيام بذلك.

الأسئلة

سؤال من الجمهور (المشار إليه فيما بعد بـ Q): - يبدو لي أنك فاتتك نقطة مهمة فيما يتعلق بـ Fan-out. هل أنا على حق في فهم أنه عندما ترسل ردًا إلى العميل، فإنك تقوم بحظره إذا كان العميل لا يريد قراءته؟

السيدة: - لا، نحن لا نمنع. أولاً، لدينا كل هذا خلف nginx، مما يعني أنه لا توجد مشاكل مع العملاء البطيئين. ثانيًا، لدى العميل قناة بها مخزن مؤقت - في الواقع، يمكننا وضع ما يصل إلى مائة تحديث هناك... إذا لم نتمكن من الكتابة إلى القناة، فسوف يقوم بحذفها. إذا رأينا أن القناة محظورة، فما علينا إلا إغلاق القناة وهذا كل شيء - سيعيد العميل الاتصال إذا ظهرت أي مشكلة. لذلك، من حيث المبدأ، لا يحدث الحجب هنا.

В: - هل لم يكن من الممكن إرسال سجل إلى الاستماع/الإشعار فورًا، وليس جدول معرفات؟

السيدة: – الاستماع/الإشعار له حد 8 آلاف بايت في التحميل المسبق الذي يرسله. من حيث المبدأ، سيكون من الممكن إرسالها إذا كنا نتعامل مع كمية صغيرة من البيانات، لكن يبدو لي أن الطريقة التي نقوم بها بذلك أكثر موثوقية. القيود موجودة في Postgres نفسه.

В: - هل يتلقى العملاء تحديثات حول المباريات التي لا يهتمون بها؟

السيدة: - بشكل عام، نعم. كقاعدة عامة، هناك 2-3 مباريات تجري بالتوازي، وهذا أمر نادر جدًا. إذا كان العميل يشاهد شيئًا ما، فهو عادةً يشاهد المباراة التي تقام. بعد ذلك، يكون لدى العميل قاعدة بيانات محلية يتم تخزين كل هذه التحديثات فيها، وحتى بدون اتصال بالإنترنت، يمكن للعميل عرض جميع المباريات السابقة التي لديه تحديثات لها. في الأساس، نقوم بمزامنة قاعدة البيانات الخاصة بنا على الخادم مع قاعدة البيانات المحلية للعميل حتى تتمكن من العمل دون اتصال بالإنترنت.

В: - لماذا قمت بإنشاء ORM الخاص بك؟

أليكسي (أحد مطوري "Smotri+"): - في ذلك الوقت (كان ذلك منذ عام) كان عدد ORMs أقل مما هو عليه الآن، على الرغم من وجود عدد كبير منهم. ما لا يعجبني أكثر في معظم ORMs الموجودة هو أن معظمها يعمل على واجهات فارغة. وهذا يعني أن الطرق في هذه ORMs جاهزة لقبول أي شيء: بنية، أو مؤشر بنية، أو رقم، أو شيء لا علاقة له بالموضوع على الإطلاق...

يقوم ORM الخاص بنا بإنشاء هياكل تعتمد على نموذج البيانات. نفسي. وهكذا فإن جميع الأساليب ملموسة، ولا تستخدم التأمل، وما إلى ذلك. إنهم يقبلون الهياكل ويتوقعون استخدام تلك الهياكل التي تأتي.

В: - كم عدد الأشخاص المشاركين؟

السيدة: - في المرحلة الأولية شارك شخصان. لقد بدأنا في مكان ما في شهر يونيو، وفي شهر أغسطس كان الجزء الرئيسي جاهزًا (النسخة الأولى). تم الإصدار في سبتمبر.

В: - عندما تصف SSE، فأنت لا تستخدم مهلة زمنية. لماذا هذا؟

السيدة: - بصراحة، SSE لا يزال بروتوكول HTML5: تم تصميم معيار SSE للتواصل مع المتصفحات، على حد علمي. إنها تحتوي على ميزات إضافية للسماح للمتصفحات بإعادة الاتصال (وإلخ)، لكننا لم نكن بحاجة إليها لأن لدينا عملاء يمكنهم تنفيذ أي منطق للاتصال والحصول على المعلومات. ما فعلناه لم يكن SSE حقًا، بل كان شيئًا مشابهًا لـ SSE. هذا ليس البروتوكول نفسه.
لم تكن هناك حاجة. بقدر ما أفهم، قام العملاء بتنفيذ آلية الاتصال عمليًا من الصفر. إنهم لم يهتموا بشكل أساسي.

В: - ما هي الأدوات الإضافية التي استخدمتها؟

السيدة: - لقد استخدمنا govet و golint بشكل نشط للحفاظ على اتساق الأسلوب، بالإضافة إلى gofmt. لم يتم استخدام أي شيء آخر.

В: - ماذا استخدمت لتصحيح الأخطاء؟

السيدة: - تم إجراء التصحيح إلى حد كبير بمساعدة الاختبارات. لم نستخدم أي مصحح أخطاء أو GOP.

В: - هل يمكنك إرجاع الشريحة التي تم فيها تنفيذ وظيفة النشر؟ هل تزعجك أسماء المتغيرات المكونة من حرف واحد؟

السيدة: - لا، لديهم مجال رؤية "ضيق" إلى حد ما. لا يتم استخدامها في أي مكان آخر باستثناء هنا (باستثناء الأجزاء الداخلية لهذه الفئة)، وهي مضغوطة للغاية - فهي تشغل 7 أسطر فقط.

В: - بطريقة ما لا يزال الأمر غير بديهي ...

السيدة: - لا، لا، هذا هو الكود الحقيقي! لا يتعلق الأمر بالأسلوب. إنها مجرد فئة عملية وصغيرة جدًا - فقط 3 حقول داخل الفئة...

ميخائيل سالوسين. اجتماع جولانج. استخدام Go في الواجهة الخلفية لتطبيق Look+

السيدة: - بشكل عام، جميع البيانات التي تتم مزامنتها مع العملاء (المباريات الموسمية، اللاعبين) لا تتغير. بالحديث تقريبًا، إذا قمنا بإنشاء رياضة أخرى نحتاج فيها إلى تغيير المباراة، فسوف نأخذ كل شيء في الاعتبار في الإصدار الجديد من العميل، وسيتم حظر الإصدارات القديمة من العميل.

В: - هل هناك أي حزم تابعة لجهات خارجية لإدارة التبعيات؟

السيدة: - لقد استخدمنا الذهاب العمق.

В: - كان هناك شيء يتعلق بالفيديو في موضوع التقرير، ولكن لم يكن هناك شيء يتعلق بالفيديو في التقرير.

السيدة: - لا، ليس لدي أي شيء في الموضوع يتعلق بالفيديوهات. يُطلق عليه اسم "Watch+" - هذا هو اسم التطبيق.

В: - قلت أنك تقوم بالبث المباشر للعملاء؟

السيدة: - لم نقم ببث أي فيديو. لقد فعلتها شركة Megafon بالكامل. نعم، لم أقل أن التطبيق من Megafon.

السيدة: - Go - لإرسال كافة البيانات - النتيجة، أحداث المباراة، الإحصائيات... Go هو البرنامج الخلفي الكامل للتطبيق. يجب على العميل أن يعرف من مكان ما الرابط الذي يجب استخدامه للاعب حتى يتمكن المستخدم من مشاهدة المباراة. لدينا روابط لمقاطع الفيديو والبثوث التي تم إعدادها.

لعب الفيديو

بعض الاعلانات 🙂

أشكركم على البقاء معنا. هل تحب مقالاتنا؟ تريد أن ترى المزيد من المحتوى المثير للاهتمام؟ ادعمنا عن طريق تقديم طلب أو التوصية للأصدقاء ، Cloud VPS للمطورين يبدأ من 4.99 دولارًا, تناظرية فريدة من خوادم المستوى المبتدئ ، اخترعناها من أجلك: الحقيقة الكاملة حول VPS (KVM) E5-2697 v3 (6 Cores) 10GB DDR4 480GB SSD 1Gbps من 19 دولارًا أو كيفية مشاركة الخادم؟ (متوفر مع RAID1 و RAID10 ، حتى 24 مركزًا وحتى 40 جيجا بايت DDR4).

Dell R730xd أرخص مرتين في مركز بيانات Equinix Tier IV في أمستردام؟ هنا فقط 2 x Intel TetraDeca-Core Xeon 2x E5-2697v3 2.6 جيجا هرتز 14C 64 جيجا بايت DDR4 4x960 جيجا بايت SSD 1 جيجابت في الثانية 100 تلفزيون من 199 دولارًا في هولندا! Dell R420 - 2x E5-2430 2.2 جيجا هرتز 6C 128 جيجا بايت DDR3 2x960 جيجا بايت SSD 1 جيجا بايت في الثانية 100 تيرا بايت - من 99 دولارًا! أقرأ عن كيفية بناء شركة البنية التحتية. فئة مع استخدام خوادم Dell R730xd E5-2650 v4 بقيمة 9000 يورو مقابل فلس واحد؟

المصدر: www.habr.com