عند تطوير نظام خادم ، من أجل التكيف مع طلبات البيانات الكبيرة والمتزامنة ، نحتاج غالبًا إلى تخزين البيانات بشكل غير متزامن ، خاصة عند العمل في نظام موزع. في هذا الوقت ، لا يمكننا الانتظار حتى يتم استرداد قاعدة بيانات الإدراج. بدلاً من ذلك ، نحتاج إلى إنشاء معرف فريد عالمي قبل إدخال قاعدة البيانات ، باستخدام المعرف الفريد العالمي. في خادم اللعبة ، يمكن استخدام المعرف الفريد العالمي لمجموعات الخادم المستقبلية ولن يكون هناك تعارض رئيسي. في المستقبل ، في حالة نمو الأعمال ، يمكن تنفيذ قاعدة البيانات والجدول المقسم. على سبيل المثال ، يجب وضع عناصر المستخدم في نفس القشرة ، وقد يتم تحديد هذا Shard بناءً على قيمة نطاق معرف المستخدم ، مثل معرف المستخدم الذي يحتوي على معرف مستخدم أكبر من 1000 وأقل من 100000 في Shard. حاليا ، ما يلي شائع الاستخدام:
1. جافا UUID.
يمكن إنشاء uuid.randomuuid (). tostring () محليًا من خلال برنامج الخدمة ، ولا يعتمد توليد المعرف على تنفيذ قاعدة البيانات.
المزايا:
قم بإنشاء معرف محليًا ولا يتطلب مكالمات عن بُعد.
العالم هو الوحيد الذي لا يتكرر.
قدرة التوسع الأفقي جيد جدًا.
عيوب:
يحتوي المعرف على 128 بت ، والتي تشغل مساحة كبيرة ويجب تخزينها كنوع سلسلة ، وكفاءة الفهرسة منخفضة للغاية.
لا يحتوي المعرف الذي تم إنشاؤه على الطابع الزمني ، ولا يمكن ضمان زيادة الاتجاه. من الصعب الاعتماد عليها عند تقسيم قواعد بيانات قاعدة البيانات.
2. طريقة REVER القائمة على Redis
يتم تشغيل Redis نفسها ذات الخيوط الواحدة ، وزيادة يضمن إجراء عملية متزايدة ذرية. كما يدعم تحديد حجم الخطوة الإضافية.
المزايا:
من السهل النشر وسهل الاستخدام. ما عليك سوى استدعاء API redis.
يمكن لخوادم متعددة مشاركة خدمة redis لتقليل وقت تطوير البيانات المشتركة.
يمكن نشر redis في مجموعات لحل مشكلة نقطة الفشل الفردية.
عيوب:
إذا كان النظام كبيرًا جدًا ، فإن طلب خدمات متعددة لإعادة Redis في نفس الوقت سيؤدي إلى اختناقات الأداء.
3. حل من وميض
يعتمد هذا الحل على معرف قاعدة البيانات التلقائي ، والذي يستخدم قاعدة بيانات منفصلة خصيصًا لإنشاء معرفات. يمكنك العثور على التفاصيل عبر الإنترنت. أنا شخصياً أعتقد أنه من المزعج للغاية استخدامه ولا ينصح باستخدامه.
4. ندفة الثلج تويتر
Snowflake هي خوارزمية توليد الهوية الموزعة التي تكون مفتوحة المصدر على Twitter. تتمثل فكرتها الأساسية في إنشاء معرف من النوع الطويل ، باستخدام 41bits بعدد عدد من المللي ثانية ، و 10 بت كرقم الماكينة ، و 12 بت كرقم متسلسل داخل المللي ثانية. يمكن أن تولد هذه الخوارزمية من الناحية النظرية ما يصل إلى 1000*(2^12) معرفات في الثانية الواحدة لكل جهاز ، أي حوالي 400 واط ، والتي يمكن أن تلبي احتياجات العمل بالكامل.
وفقًا لفكرة خوارزمية Snowflake ، يمكننا إنشاء معرفنا الفريد العالمي استنادًا إلى سيناريوهات أعمالنا. نظرًا لأن طول النوع الطويل في Java هو 64 بايت ، يجب التحكم في المعرف الذي صممه في 64 بايت.
المزايا: أداء عالي ، زمن انتقال منخفض ؛ تطبيق مستقل ؛ منظم حسب الوقت.
العيوب: التطوير المستقل والنشر مطلوبان.
على سبيل المثال ، يحتوي المعرف الذي صممه على المعلومات التالية:
| 41 بت: الطابع الزمني | 3 بت: المنطقة | 10 بت: رقم الآلة | 10 بت: الرقم التسلسلي |
رمز Java الذي يولد معرف فريد:
/*** مولد معرف مخصص* قواعد توليد المعرف: معرف يصل إلى 64 بت ** | 41 بت: الطابع الزمني (MS) | 3 بت: المنطقة (غرفة الكمبيوتر) | 10 بت: رقم الآلة | 10 بت: الرقم التسلسلي |*/الفئة العامة gameuuid {// وقت المرجع الخاص الطويل الطويل = 1288834974657L ؛ // الخميس ، 04 نوفمبر 2010 01:42:54 GMT // أرقام العلم المنطقة الخاصة الطويلة الطويلة regitidbits = 3l ؛ الحد الأقصى لقيمة معرف الجهاز الخاص النهائي الأساسي الطويل الطويل maxworkerid = -1l ^ (-1l << workerIdBits) ؛ // أقصى قيمة للرقم التسلسلي معرف المعرف النهائي الثابتة الطويلة الطويلة = -1L ^ regitedshift الطويل الثابت = sequenceBits + WorkerIdBits ؛ // يتم تحويل الوقت اليسار بمقدار 23 بتات خاصة نهائية طويلة الطويلة الطويلة الطويلة = sequenceBits + WorkerIdBits + regionidbits ؛ ثابت خاص طويل LastTimestamp = -1L ؛ تسلسل طويل خاص = 0L ؛ عمل نهائي طويل. نهائي خاص طويل الأساليد ؛ gamuuuid العام (عامل طويل ، long reghedid) {// إذا كان خارج النطاق ، يتم طرح استثناء إذا (workerId> maxworkerid || workerid <0) ٪ d أو أقل من 0 ") ؛} this.workerid = workerId ؛ this.regionId = regiveId ؛} gameuuid (عامل طويل) {// إذا تم إلقاء خارج النطاق إذا (workerId> maxworkerid || workerid <0) {throw new alficalArgumentException ( this.nextid (false ، 0) ؛}/*** الكود الفعلي الذي تم إنشاؤه بواسطة param isPadding* @param usid* @return*/private synchronized long nextid (ispadding boolean ، long busid) {timestamp = timegen () {رمي استثناء جديد ("تم نقل الساعة إلى الوراء. رفض إنشاء معرف" + (LastTimestamp - Timestamp) + "ملايين الملايين") ؛} catch (استثناء e) {E.PrintStackTrace () ؛ يزداد من تلقاء نفسه ، لأن التسلسل هو 10 بت فقط ، ويتم دمجه مع تسلسل التسلسل وإزالة التسلسل عالي بت = (تسلسل + 1) و SequencEmask ؛ // الحكم على ما إذا كان يفيض ، أي أنه يتجاوز 1024 في كل ميلي ثانية. عندما يكون 1024 ، يتم دمجه مع SequencEmask ، ويساوي التسلسل 0if (sequence == 0) {// spin ينتظر حتى الطابع الزمني millisecond التالي = tailnextmillis (lastTimestamp) ؛}} آخر {// إذا كان التسلسل مختلفًا عن الجيل الأخير ، فإن إعادة تعيين التسلسل ، والذي يبدأ في Millisson التالي. // من أجل ضمان مزيد من العشوائية من mantissa ، قم بتعيين رقم عشوائي في تسلسل البت الأخير = securerandom الجديد () (PaddingNum << regionidshift) | (عامل << WorkerIdShift) | تسلسل ؛} // منع وقت التوليد من الوقت الأصغر من الوقت السابق (بسبب مشاكل مثل رد الاتصال NTP) ، والحفاظ على الاتجاه الإضافي. timegen () {return System.CurrentTimeMillis () ؛}}بعض الأشياء التي يجب ملاحظتها عند استخدام الطرق المخصصة:
من أجل الحفاظ على اتجاه النمو ، من الضروري تجنب وقت بعض الخوادم في وقت مبكر وبعض الخوادم متأخرة ، لذلك يجب التحكم في وقت جميع الخوادم ، والوقت الذي يتم فيه تجنب خادم وقت NTP إلى الخادم ؛ عند عبور المللي ثانية ، يصل الرقم التسلسلي دائمًا إلى 0 ، والذي سيجعل المزيد من المعرفات مع الرقم التسلسلي 0 ، مما يؤدي إلى معرفات غير متساوية بعد التعديل ، وبالتالي فإن الرقم التسلسلي لا ينتمي إلى 0 في كل مرة ، ولكن رقم عشوائي من 0 إلى 9.
يمكننا اختيار الأساليب المذكورة أعلاه وفقًا لاحتياجاتنا. في تطوير خادم اللعبة ، يمكنك الاختيار وفقًا لنوع اللعبة الخاص بك ، مثل ألعاب الهاتف المحمول ، ويمكنك استخدام طريقة Redis البسيطة ، وهي بسيطة وليس من السهل ارتكاب أخطاء. نظرًا لأن عدد المعرفات الجديدة التي تم إنشاؤها بواسطة خوادم واحدة في هذا النوع من الألعاب ليست كبيرة جدًا ، فقد تلبي الاحتياجات تمامًا. بالنسبة لخوادم الألعاب العالمية الكبيرة ، يتم توزيعها بشكل أساسي ، حتى تتمكن من استخدام ندفة الثلج. يعد رمز ندفة الثلج أعلاه مجرد مثال ويجب تخصيصه وفقًا لاحتياجاتك ، لذلك هناك حجم تطوير إضافي ، ويجب أن تنتبه إلى الاحتياطات المذكورة أعلاه.
ما سبق هو ملخص لطرق استخدام رمز Java لتنفيذ خادم اللعبة لإنشاء معرف فريد عالمي يعتمد على رمز Java. آمل أن يكون ذلك مفيدًا للجميع. إذا كان لديك أي أسئلة ، فيرجى ترك رسالة لي وسوف يرد المحرر على الجميع في الوقت المناسب. شكرا جزيلا لدعمكم لموقع wulin.com!