SocketIO Giao tiếp với một cổng giữa khách hàng và dịch vụ?


8

Ý chính

Tôi có một ứng dụng chạy trên kiến ​​trúc dựa trên microservice (trên Kubernetes). Tất cả các giao tiếp đến / từ bên ngoài ứng dụng xảy ra thông qua API Gateway .

Điều đó chỉ có nghĩa là các yêu cầu từ frontend của tôi không trực tiếp đến các dịch vụ, nhưng chúng phải đi qua Cổng.

Động cơ

Bây giờ tôi cần triển khai một tính năng yêu cầu giao tiếp thời gian thực giữa giao diện và dịch vụ nội bộ. Nhưng vì dịch vụ nội bộ không được tiếp xúc với bên ngoài, tôi cần một cách để "định tuyến" dữ liệu thời gian thực thông qua Cổng.

Tất cả các dịch vụ của tôi đang chạy trên Node.js, đó là lý do tôi muốn sử dụng Socket.IO để thực hiện giao tiếp thời gian thực.

ngành kiến ​​trúc

Vấn đề

Nhưng làm thế nào để thực hiện mũi tên kép màu tím từ bản phác thảo?

Vì vậy, thông thường máy khách frontend sẽ kết nối với máy chủ nơi Socket.IO đang chạy. Nhưng trong trường hợp của tôi, máy chủ này (máy chủ tính năng thời gian thực) không thể truy cập được từ máy khách (và không bao giờ nên), điều đó có nghĩa là máy khách phải kết nối với Cổng. Do đó, Gateway cần thực hiện một số cơ chế để định tuyến tất cả các tin nhắn đến dịch vụ thời gian thực và ngược lại.

Ý tưởng

(1) Có máy chủ HTTP thứ hai lắng nghe các sự kiện trên Cổng và phát ra các sự kiện đó đến máy chủ thời gian thực. Theo hướng khác, máy chủ thời gian thực sẽ phát ra các sự kiện đến Cổng, sau đó sẽ phát chúng ra giao diện. Tôi nghĩ rằng phương pháp này chắc chắn sẽ hiệu quả, nhưng dường như dư thừa để phát ra mọi thứ hai lần. Và nó chắc chắn sẽ làm tổn thương hiệu suất?

(2) Sử dụng Bộ điều hợp Socket.IO để " truyền sự kiện giữa các nút ", đây có vẻ là cách đúng đắn vì nó được sử dụng để "truyền tin nhắn giữa các tiến trình hoặc máy tính". Nhưng tôi có vấn đề khi bắt đầu vì thiếu tài liệu / ví dụ. Tôi cũng không sử dụng Redis (có cần sử dụng bộ chuyển đổi không?)

(3) Sử dụng gói socket.io-emitter , có vẻ như không phải là một lựa chọn tốt vì lần cam kết cuối cùng là từ 3 năm trước.

(4) Cái gì khác?


Vì vậy, bạn phải sử dụng API Gateway để chuyển hướng lưu lượng truy cập? Chúng tôi có socket.io được triển khai trong ứng dụng đổ nhưng dịch vụ đã triển khai trong một dịch vụ riêng biệt (nhóm). Sử dụng ingress-controllerk8s sẽ gửi socketlưu lượng đến dịch vụ bóng đá.
Giorgio Cerruti

@GiorgioCerruti Không tôi không phải sử dụng Cổng, nhưng đây là cách tôi lên kế hoạch cho ứng dụng của mình hoạt động. Vì vậy, bạn muốn giới thiệu "dịch vụ nội bộ" của tôi thông qua Ingress?
Florian Ludewig

Tôi đã làm nó bằng cách sử dụng nginxnhư một bộ điều khiển xâm nhập. Bạn có thể sử dụng haproxy là tốt nếu bạn thích. Bạn sẽ có 2 dịch vụ (triển khai) 1 để quản lý các yêu cầu HTTP và 1 để quản lý các yêu cầu ổ cắm. Sử dụng xâm nhập, bạn có thể hiển thị đường dẫn và chuyển hướng lưu lượng truy cập đến đúng dịch vụ, ví dụ: mọi yêu cầu được nhấn /socketsẽ được chuyển hướng đến socket-serviceứng dụng.
Giorgio Cerruti

ok nghe có vẻ như một cái gì đó đang cố gắng, bởi vì tôi đã sử dụng nginx Ingress. Nó sẽ là tuyệt vời nếu bạn có thể gửi câu trả lời giới thiệu làm thế nào để thực hiện nó (đây là cấu hình xâm nhập Tôi hiện đang sử dụng: github.com/flolu/centsideas/blob/... )
Florian Ludewig

Câu trả lời:


3

Được rồi, về cơ bản tôi đã thiết kế ứng dụng như thế này

Xâm nhập

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: centsideas-ingress
  annotations:
    kubernetes.io/tls-acme: 'true'
    kubernetes.io/ingress.class: 'nginx'
    cert-manager.io/cluster-issuer: letsencrypt
spec:
  tls:
    - hosts:
        - centsideas.com
        - api.centsideas.com
      secretName: centsideas-tls
  rules:
    - host: api.centsideas.com
      http:
        paths:
          - path: /socker.io
            backend: 
             serviceName: socket-service
             servicePort: 8000
          -  path: /
             backend:
              serviceName: centsideas-gateway
              servicePort: 3000
    - host: centsideas.com
      http:
        paths:
          - backend:
              serviceName: centsideas-client
              servicePort: 8080

Dịch vụ

apiVersion: v1
kind: Service
metadata:
 name: socket-service
 annotations:
  service.beta.kubernetes.io/external-traffic: "OnlyLocal" 
 namespace: namespace
spec:
 sessionAffinity: ClientIP
 ports:
  - name: ws-port
    protocol: TCP
    port: 8000
 type: ClusterIP
 selector:
  service: ws-api

Sau đó, bạn tạo triển khai của mình để triển khai dịch vụ ws. Giống như thế này, bạn cũng có thể kích hoạt k8s HPA (autoscaling ngang) để mở rộng dịch vụ socket.io. Bạn phải thay đổi chú thích và các tùy chọn khác dựa trên phiên bản k8 của bạn (Tôi nghĩ rằng chú thích service.beta.kubernetes.io/external-traffic: "OnlyLocal"đã không được chấp nhận).


Ồ tuyệt! Chỉ cần làm rõ: đối với mọi dịch vụ nội bộ yêu cầu ổ cắm web tôi sẽ thêm dịch vụ khác socket-servicevà thêm nó vào Ingress?
Florian Ludewig

Nó phụ thuộc. Nếu bạn cần trưng ra các dịch vụ mới (codebase mới), bạn phải tạo các dịch vụ k8 mới cho mỗi microservice. Thay vào đó, nếu bạn cần mở rộng quy mô ứng dụng socket.io của mình (tạo thêm phiên bản của cùng một cơ sở mã), thì không, bạn không nên. Một dịch vụ về cơ bản là một LoadBalancer được tạo bởi k8s bằng iptables, nó sẽ cân bằng yêu cầu của bạn giữa các trường hợp quyết định bởi pod của nó không bận với các yêu cầu / tài nguyên.
Giorgio Cerruti

Có ý nghĩa, nó phụ thuộc vào trường hợp sử dụng :) Vì vậy, tôi sẽ đợi một vài ngày trong trường hợp tôi sẽ nhận được một số câu trả lời khác. Nếu không bạn sẽ nhận được tiền thưởng, cảm ơn bạn!
Florian Ludewig

0

Vì dịch vụ nội bộ không được tiếp xúc với bên ngoài, tôi khuyên bạn nên sử dụng đường hầm. ngrok là một lệnh cho một URL tức thời và an toàn đến máy chủ localhost của bạn thông qua bất kỳ NAT hoặc tường lửa. Nếu máy chủ của bạn hiển thị dịch vụ ổ cắm thông qua một cổng nhất định, sử dụng ngrok để tạo proxy ngược để hiển thị thế giới mà bạn có thể kết nối với ứng dụng lối vào của mình. Sử dụng lệnh này rất đơn giản, đây là một ví dụ về cách sử dụng nó:

  1. Đăng ký và tải tập tin ngrok tại địa chỉ sau Trang web chính thức
  2. Chỉ cần chạy các hướng dẫn sau để làm cho nó hoạt động

    ./ngrok http 3000

  3. Để làm cho nó vĩnh viễn, bạn phải tạo một dịch vụ và sử dụng tệp ngrok.yml để có cấu hình tốt nhất.

Đây là tài liệu chính thức ở đây


Tôi có lẽ không đủ chính xác trong câu trả lời của tôi. Cách tiếp cận của bạn có thể hoạt động, nhưng dịch vụ nội bộ phải ở bên trong. Không ai từ bên ngoài có thể nói chuyện với nó bằng một kết nối trực tiếp
Florian Ludewig
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.