بضع كلمات حول R2DBC و PostgreSQL

في الآونة الأخيرة ، أرى مرة أخرى أن الضجيج قد تكثف حول البرمجة التفاعلية بشكل عام ، والعمل التفاعلي مع قواعد البيانات على وجه الخصوص. لدي بعض العبارات التي أود أن أقولها عن هذا.

صورة

دعني أذكرك بما حدث في السلسلة السابقة. في نهاية عام 2017 ، خرج Spring 5 ، حيث ظهر دعم البرمجة التفاعلية. على وجه الخصوص ، نحن نتحدث عن WebFlux . بدأ الجميع في تجربة هذه التقنية بشكل حاد (منحنى الضجيج النموذجي) ، ثم أدركت الصناعة أنه ليس الجميع بحاجة إلى رد الفعل. الدروس الرئيسية المستفادة:

  • البرمجة التفاعلية أكثر صعوبة في التصحيح
  • إن تطوير الأنظمة التفاعلية أكثر صعوبة من الأنظمة الكلاسيكية المحجوبة ؛ إذا قمت بحظر الخيط دون قصد ، فقد انتهيت. لهذا السبب ظهر المشروع (أحد المؤلفين -bsideup )
  • البرمجة التفاعلية ، ولا سيما المرونة ، مطلوبة بشكل أساسي عند الأحمال العالية a la Netflix. إذا كان لديك 100 RPS ، فمن المحتمل أن تكتب رمزًا بأسلوب الحظر - فهي أرخص وأسهل

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

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

في السنوات الأخيرة ، بدأ سباق كبير في تطوير برامج تشغيل بديلة لـ PostgreSQL ، والتي تضمنت تطوير واجهة برمجة تطبيقات غير متزامنة. حتى Oracle حاولت القيام بذلك ، لكنها أغلقت بالفعل التنمية لصالح مشروع Loom وأليافه . ولكن بعد ذلك فكرت شركة أوراكل في الأمر بشكل أفضل وبدأت في القيام بذلك مرة أخرى .

هناك 3 حلول الآن:

  1. https://github.com/jasync-sql/jasync-sql - برنامج تشغيل غير متزامن لـ PostgreSQL ، مكتوب بلغة Kotlin ، حيث Netty هو وسيلة النقل
  2. الحل الذي يستخدمه Vert.x هو https://github.com/mauricio/postgresql-async . من الجدير بالذكر أن المشروع مؤرشف ، وأن برنامج تشغيل jasync-sql السابق يعيد الكتابة بنفس الطريقة (على الرغم من أن الأصل مكتوب في Scala ، والحل الجديد مكتوب في Kotlin).
    تحديث تم تصحيح لي في التعليقات ، العميل من Vert.x على قيد الحياة ويشعر بالارتياح في المعايير .
  3. السائق من فريق الربيع هو https://github.com/r2dbc/r2dbc-postgresql . يوفر برنامج التشغيل هذا على الفور واجهة برمجة تطبيقات تفاعلية (وليست متزامنة) ، ويتم استخدام Netty للنقل ، كما هو الحال في jasync-sql.

من الناحية النظرية ، تم بناء هذه الدوافع على مبادئ مماثلة. جميعهم يستخدمون ميزات PostgreSQL الموجودة حصريًا:


للأسف ، لا يمكن للسائقين تغيير Postgres لبروتوكول Wire (كما لو أن Oleg Dokuk لا يريد ذلك - https://www.youtube.com/watch؟v=n9tL2I_Big8 ). أي أن Postgres لا يزال يتطلب اتصالاً منفصلاً لاستعلام SELECT. بالإضافة إلى ذلك ، تقوم Postgres أيضًا بإنشاء عملية جديدة لكل اتصال - https://www.postgresql.org/docs/current/tutorial-arch.html .

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

هذا ، لتلخيص. تعمل محركات PG التفاعلية (أو غير المتزامنة) على تحسين الوضع في التطبيقات (نستخدم الآن الإدخال / الإخراج غير المحظور القائم على Netty ، وليس إنفاق سلسلة محادثات على استعلام) ، ولكن على وجه التحديد على جانب PostgreSQL - الأمور ليست جيدة (دعنا نأمل في تحسين بروتوكول الشبكة وبنية قاعدة البيانات )

أي سائق يجب أن تنظر إليه عن كثب؟ إذا كنت مثلي تستخدم Spring في عملك ، فربما يكون r2dbc-postgresql خيارًا جيدًا. من المهم أنه في أحدث الإصدارات من إطار عملهم ، قام الرجال من Pivotal بدمج السائق بشكل جيد مع الأشياء المعتادة ، على سبيل المثال ، مع Spring Data R2DBC(هذا لا يزال RC). ونتيجة لذلك ، لا يتعين علينا العمل مع واجهة برمجة تطبيقات سائق منخفضة المستوى وتجمع الاتصال ، مما يقلل من احتمالية ارتكاب خطأ في مثل هذا المشروع المعقد.

يبدو الحد الأدنى من المثال (الذي تجسست فيه بنجاح في التوثيق) باستخدام Spring Data R2DBC مألوفًا جدًا:

1. تكوين بيانات الاعتماد وتجمع الاتصال:

spring.r2dbc.username=postgres
spring.r2dbc.password=P4$$W0RddD
spring.r2dbc.url=r2dbc:postgresql://localhost:5432/r2dbc
spring.r2dbc.pool.enabled=true
spring.r2dbc.pool.initial-size=10
spring.r2dbc.pool.max-idle-time=1m
spring.r2dbc.pool.max-size=30
spring.data.r2dbc.repositories.enabled=true

2. إنشاء كيان:

public class Customer {
    @Id
    private Long id;

    private String firstName;

    private String lastName;

    public Customer(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }
}

3. إنشاء المستودع المعتاد:

public interface CustomerRepository extends ReactiveCrudRepository<Customer, Long> {
}

4. استخدم المستودع:

@RestController
@RequestMapping("/")
public class CustomerController {

    private CustomerRepository customerRepository;

    @PostMapping("/customer")
    Mono<Void> create(@RequestBody Publisher<Customer> customerFlux) {
        return customerRepository.saveAll(customerFlux).then();
    }

    @GetMapping("/customer")
    public Flux<Customer> list() {
        return customerRepository.findAll();
    }

    @GetMapping("/customer/{id}")
    public Mono<Customer> findById(@PathVariable Long id) {
        return customerRepository.findById(id);
    }
}

يمكن العثور على مثال كامل في هذا المستودع - https://github.com/Hixon10/spring-boot-r2dbc-postgresql-example .

أخيرًا ، دعنا نتحدث عن المهم: هل تحتاج إلى استخدام r2dbc الآن في تطبيقاتك؟ في رأيي - من السابق لأوانه. كنت أنتظر إصدار مجموعة من التقنيات (برنامج التشغيل ، Spring DATA) ، وجمع أول المخازن. أعتقد أنه في عام 2021 سيكون من الممكن بالفعل النظر إلى هذا السائق عن كثب.

الوضع الحالي - النظام التفاعلي بأكمله (برنامج تشغيل قاعدة بيانات Spring WebFlux + R2DBC) يبدو رائعًا جدًا. حرفيا اليومأوليغشيرنشر ملخص التي يوجد فيها رابط لمقال مع المعايير - https://technology.amis.nl/2020/04/10/spring-blocking-vs-non-blocking-r2dbc-vs-jdbc-and-webflux-vs- الويب mvc / . باختصار - يفوز التفاعل.

All Articles