“Đi trong đôi giày của tôi” - chờ đã, chúng có được đánh dấu không?

Từ năm 2019, Nga đã có luật bắt buộc ghi nhãn. Luật không áp dụng cho tất cả các nhóm hàng hóa và ngày bắt đầu có hiệu lực ghi nhãn bắt buộc đối với các nhóm sản phẩm cũng khác nhau. Thuốc lá, giày dép và thuốc sẽ là những mặt hàng đầu tiên phải dán nhãn bắt buộc; các sản phẩm khác sẽ được bổ sung sau, ví dụ như nước hoa, dệt may và sữa. Sự đổi mới về mặt lập pháp này đã thúc đẩy sự phát triển của các giải pháp CNTT mới giúp có thể theo dõi toàn bộ chuỗi vòng đời của sản phẩm từ sản xuất đến mua hàng của người tiêu dùng cuối cùng, tới tất cả những người tham gia vào quy trình: cả chính nhà nước và tất cả các tổ chức bán hàng hóa với ghi nhãn bắt buộc.

Ở X5, hệ thống sẽ theo dõi hàng hóa được dán nhãn và trao đổi dữ liệu với nhà nước và nhà cung cấp được gọi là “Marcus”. Hãy cho bạn biết thứ tự ai và cách nào đã phát triển nó, nền tảng công nghệ của nó là gì và tại sao chúng tôi có điều gì đó đáng tự hào.

“Đi trong đôi giày của tôi” - chờ đã, chúng có được đánh dấu không?

Tải thật cao

“Marcus” giải quyết được nhiều vấn đề, trong đó chính là sự tương tác tích hợp giữa hệ thống thông tin X5 và hệ thống thông tin trạng thái về sản phẩm được dán nhãn (GIS MP) để theo dõi chuyển động của sản phẩm được dán nhãn. Nền tảng này cũng lưu trữ tất cả các mã ghi nhãn mà chúng tôi nhận được và toàn bộ lịch sử di chuyển của các mã này giữa các đối tượng, đồng thời giúp loại bỏ việc phân loại lại các sản phẩm được dán nhãn. Sử dụng ví dụ về các sản phẩm thuốc lá, được bao gồm trong nhóm hàng hóa được dán nhãn đầu tiên, chỉ một xe tải thuốc lá chứa khoảng 600 gói, mỗi gói có mã riêng. Và nhiệm vụ của hệ thống của chúng tôi là theo dõi và xác minh tính hợp pháp của việc di chuyển từng gói hàng như vậy giữa các nhà kho và cửa hàng, đồng thời cuối cùng xác minh khả năng chấp nhận bán chúng cho người mua cuối cùng. Và chúng tôi ghi lại khoảng 000 giao dịch tiền mặt mỗi giờ và chúng tôi cũng cần ghi lại cách mỗi gói hàng như vậy được đưa vào cửa hàng. Do đó, có tính đến tất cả các chuyển động giữa các đối tượng, chúng tôi mong đợi hàng chục tỷ bản ghi mỗi năm.

Đội M

Mặc dù thực tế rằng Marcus được coi là một dự án trong X5 nhưng nó vẫn đang được triển khai bằng cách sử dụng phương pháp tiếp cận sản phẩm. Nhóm làm việc theo Scrum. Dự án bắt đầu vào mùa hè năm ngoái, nhưng kết quả đầu tiên chỉ đến vào tháng 16 - nhóm của chúng tôi đã được lắp ráp hoàn chỉnh, kiến ​​trúc hệ thống được phát triển và thiết bị đã được mua. Hiện nhóm có XNUMX người, trong đó có XNUMX người tham gia phát triển backend và frontend, XNUMX người trong số đó tham gia phân tích hệ thống. Thêm sáu người nữa tham gia vào việc kiểm tra thủ công, tải trọng, tự động hóa và bảo trì sản phẩm. Ngoài ra, chúng tôi còn có chuyên gia SRE.

Đội ngũ của chúng tôi không chỉ viết code mà hầu hết mọi người đều biết lập trình và viết autotest, loading script và Automation script. Chúng tôi đặc biệt chú ý đến điều này vì ngay cả việc hỗ trợ sản phẩm cũng yêu cầu mức độ tự động hóa cao. Chúng tôi luôn cố gắng tư vấn và giúp đỡ những đồng nghiệp chưa từng lập trình trước đây và giao cho họ một số nhiệm vụ nhỏ để thực hiện.

Do đại dịch virus Corona, chúng tôi đã chuyển toàn bộ nhóm sang làm việc từ xa; sự sẵn có của tất cả các công cụ để quản lý phát triển, quy trình làm việc được xây dựng trong Jira và GitLab đã giúp chúng tôi có thể dễ dàng vượt qua giai đoạn này. Những tháng làm việc từ xa cho thấy năng suất của nhóm không bị ảnh hưởng; đối với nhiều người, sự thoải mái trong công việc tăng lên, điều duy nhất còn thiếu là giao tiếp trực tiếp.

Cuộc họp nhóm từ xa

“Đi trong đôi giày của tôi” - chờ đã, chúng có được đánh dấu không?

Các cuộc họp khi làm việc từ xa

“Đi trong đôi giày của tôi” - chờ đã, chúng có được đánh dấu không?

Nhóm công nghệ của giải pháp

Kho lưu trữ và công cụ CI/CD tiêu chuẩn cho X5 là GitLab. Chúng tôi sử dụng nó để lưu trữ mã, thử nghiệm liên tục và triển khai đến các máy chủ thử nghiệm và sản xuất. Chúng tôi cũng sử dụng phương pháp đánh giá mã khi có ít nhất 2 đồng nghiệp cần phê duyệt những thay đổi do nhà phát triển thực hiện đối với mã. Máy phân tích mã tĩnh SonarQube và JaCoCo giúp chúng tôi giữ mã của mình sạch sẽ và đảm bảo mức độ bao phủ kiểm thử đơn vị cần thiết. Tất cả các thay đổi đối với mã phải trải qua các bước kiểm tra này. Tất cả các tập lệnh kiểm tra được chạy thủ công sau đó sẽ được tự động hóa.

Để triển khai thành công các quy trình kinh doanh của “Marcus”, chúng tôi phải giải quyết một số vấn đề công nghệ, theo thứ tự từng vấn đề.

Nhiệm vụ 1. Sự cần thiết của khả năng mở rộng theo chiều ngang của hệ thống

Để giải quyết vấn đề này, chúng tôi đã chọn cách tiếp cận kiến ​​trúc vi dịch vụ. Đồng thời, điều rất quan trọng là phải hiểu các lĩnh vực trách nhiệm của dịch vụ. Chúng tôi đã cố gắng chia chúng thành các hoạt động kinh doanh, có tính đến các chi tiết cụ thể của quy trình. Ví dụ, việc nghiệm thu tại kho không phải là hoạt động thường xuyên nhưng có quy mô rất lớn, trong thời gian đó cần nhanh chóng nhận được thông tin từ cơ quan quản lý nhà nước về các đơn vị hàng hóa được chấp nhận, số lượng trong một lần giao hàng lên tới 600000 , kiểm tra khả năng chấp nhận sản phẩm này vào kho và trả lại đầy đủ thông tin cần thiết cho hệ thống tự động hóa kho. Tuy nhiên, việc vận chuyển từ kho có cường độ lớn hơn nhiều nhưng đồng thời hoạt động với khối lượng dữ liệu nhỏ.

Chúng tôi triển khai tất cả các dịch vụ trên cơ sở không trạng thái và thậm chí cố gắng chia các hoạt động nội bộ thành các bước, sử dụng cái mà chúng tôi gọi là chủ đề tự Kafka. Đây là khi một vi dịch vụ gửi tin nhắn đến chính nó, cho phép bạn cân bằng tải cho các hoạt động sử dụng nhiều tài nguyên hơn và đơn giản hóa việc bảo trì sản phẩm, nhưng còn nhiều điều hơn thế nữa về sau.

Chúng tôi quyết định tách các mô-đun tương tác với hệ thống bên ngoài thành các dịch vụ riêng biệt. Điều này giúp giải quyết vấn đề API thay đổi thường xuyên của các hệ thống bên ngoài mà hầu như không ảnh hưởng đến các dịch vụ có chức năng kinh doanh.

“Đi trong đôi giày của tôi” - chờ đã, chúng có được đánh dấu không?

Tất cả các vi dịch vụ đều được triển khai trong cụm OpenShift, điều này giải quyết cả vấn đề mở rộng quy mô từng vi dịch vụ và cho phép chúng tôi không sử dụng các công cụ Khám phá dịch vụ của bên thứ ba.

Nhiệm vụ 2. Sự cần thiết phải duy trì tải trọng cao và trao đổi dữ liệu rất chuyên sâu giữa các dịch vụ nền tảng: Chỉ riêng trong giai đoạn khởi động dự án, khoảng 600 thao tác mỗi giây được thực hiện. Chúng tôi hy vọng giá trị này sẽ tăng lên 5000 hoạt động/giây khi các cửa hàng bán lẻ kết nối với nền tảng của chúng tôi.

Vấn đề này đã được giải quyết bằng cách triển khai cụm Kafka và gần như loại bỏ hoàn toàn sự tương tác đồng bộ giữa các dịch vụ vi mô của nền tảng. Điều này đòi hỏi phải phân tích rất cẩn thận các yêu cầu của hệ thống, vì không phải tất cả các hoạt động đều có thể không đồng bộ. Đồng thời, chúng tôi không chỉ truyền tải sự kiện thông qua nhà môi giới mà còn truyền tải toàn bộ thông tin doanh nghiệp cần có trong tin nhắn. Do đó, kích thước tin nhắn có thể lên tới vài trăm kilobyte. Giới hạn kích thước tin nhắn trong Kafka yêu cầu chúng ta phải dự đoán chính xác kích thước tin nhắn, nếu cần thì chia nhỏ ra nhưng việc phân chia phải logic, liên quan đến hoạt động nghiệp vụ.
Ví dụ: chúng tôi chia hàng hóa được chở bằng ô tô vào các hộp. Đối với các hoạt động đồng bộ, các dịch vụ vi mô riêng biệt được phân bổ và tiến hành kiểm tra tải kỹ lưỡng. Việc sử dụng Kafka đặt ra cho chúng tôi một thách thức khác - việc kiểm tra hoạt động dịch vụ của chúng tôi có tính đến việc tích hợp Kafka khiến tất cả các bài kiểm tra đơn vị của chúng tôi không đồng bộ. Chúng tôi đã giải quyết vấn đề này bằng cách viết các phương thức tiện ích của riêng mình bằng cách sử dụng Nhà môi giới Kafka nhúng. Điều này không loại bỏ nhu cầu viết bài kiểm tra đơn vị cho từng phương pháp, nhưng chúng tôi muốn kiểm tra các trường hợp phức tạp bằng Kafka.

Người ta chú ý rất nhiều đến việc theo dõi nhật ký để TraceId của chúng không bị mất khi xảy ra ngoại lệ trong quá trình vận hành dịch vụ hoặc khi làm việc với lô Kafka. Và nếu không có vấn đề đặc biệt nào với cái đầu tiên, thì trong trường hợp thứ hai, chúng tôi buộc phải ghi lại tất cả các TraceId mà lô đi kèm và chọn một cái để tiếp tục truy tìm. Sau đó, khi tìm kiếm bằng TraceId ban đầu, người dùng sẽ dễ dàng tìm ra dấu vết nào tiếp tục.

Nhiệm vụ 3. Nhu cầu lưu trữ lượng lớn dữ liệu: Hơn 1 tỷ nhãn mỗi năm cho riêng thuốc lá đều đến với X5. Họ yêu cầu truy cập liên tục và nhanh chóng. Tổng cộng, hệ thống phải xử lý khoảng 10 tỷ hồ sơ về lịch sử di chuyển của những hàng hóa được dán nhãn này.

Để giải quyết vấn đề thứ ba, cơ sở dữ liệu NoSQL MongoDB đã được chọn. Chúng tôi đã xây dựng một phân đoạn gồm 5 nút và mỗi nút có một Bộ bản sao gồm 3 máy chủ. Điều này cho phép bạn mở rộng hệ thống theo chiều ngang, thêm máy chủ mới vào cụm và đảm bảo khả năng chịu lỗi của nó. Ở đây, chúng tôi gặp phải một vấn đề khác - đảm bảo tính giao dịch trong cụm mongo, có tính đến việc sử dụng các vi dịch vụ có thể mở rộng theo chiều ngang. Ví dụ: một trong những nhiệm vụ của hệ thống của chúng tôi là xác định các nỗ lực bán lại sản phẩm có cùng mã ghi nhãn. Ở đây, các lớp phủ xuất hiện với các lần quét sai hoặc các thao tác sai sót của nhân viên thu ngân. Chúng tôi nhận thấy rằng những sự trùng lặp như vậy có thể xảy ra cả trong một lô Kafka đang được xử lý và trong hai lô được xử lý song song. Vì vậy, việc kiểm tra các bản sao bằng cách truy vấn cơ sở dữ liệu không mang lại kết quả gì. Đối với mỗi vi dịch vụ, chúng tôi giải quyết vấn đề riêng biệt dựa trên logic kinh doanh của dịch vụ này. Ví dụ: đối với séc, chúng tôi đã thêm séc bên trong hàng loạt và xử lý riêng để tránh sự xuất hiện của các bản sao khi chèn.

Để đảm bảo rằng công việc của người dùng với lịch sử hoạt động không ảnh hưởng đến điều quan trọng nhất - hoạt động của các quy trình kinh doanh của chúng tôi, chúng tôi đã tách tất cả dữ liệu lịch sử thành một dịch vụ riêng biệt với cơ sở dữ liệu riêng, cũng nhận thông tin qua Kafka . Bằng cách này, người dùng làm việc với một dịch vụ biệt lập mà không ảnh hưởng đến các dịch vụ xử lý dữ liệu cho các hoạt động đang diễn ra.

Nhiệm vụ 4: Xử lý và giám sát hàng đợi:

Trong các hệ thống phân tán, các vấn đề và lỗi chắc chắn phát sinh về tính sẵn có của cơ sở dữ liệu, hàng đợi và nguồn dữ liệu bên ngoài. Trong trường hợp của Marcus, nguồn gốc của những lỗi đó là do sự tích hợp với các hệ thống bên ngoài. Cần phải tìm ra giải pháp cho phép các yêu cầu lặp lại đối với các phản hồi sai với một số thời gian chờ được chỉ định, nhưng đồng thời không ngừng xử lý các yêu cầu thành công trong hàng đợi chính. Vì mục đích này, khái niệm được gọi là “thử lại dựa trên chủ đề” đã được chọn. Đối với mỗi chủ đề chính, một hoặc nhiều chủ đề thử lại được tạo để gửi các tin nhắn sai, đồng thời loại bỏ sự chậm trễ trong việc xử lý các tin nhắn từ chủ đề chính. Sơ đồ tương tác -

“Đi trong đôi giày của tôi” - chờ đã, chúng có được đánh dấu không?

Để triển khai sơ đồ như vậy, chúng tôi cần những điều sau: tích hợp giải pháp này với Spring và tránh trùng lặp mã. Trong khi lướt web, chúng tôi đã tìm thấy một giải pháp tương tự dựa trên Spring BeanPostProccessor, nhưng nó có vẻ cồng kềnh một cách không cần thiết đối với chúng tôi. Nhóm của chúng tôi đã tạo ra một giải pháp đơn giản hơn cho phép chúng tôi tích hợp vào chu kỳ Mùa xuân để tạo người tiêu dùng và thêm Người tiêu dùng thử lại. Chúng tôi đã cung cấp nguyên mẫu giải pháp của mình cho nhóm Spring, bạn có thể xem nó đây. Số lượng Người tiêu dùng thử lại và số lần thử cho mỗi người tiêu dùng được định cấu hình thông qua các tham số, tùy thuộc vào nhu cầu của quy trình kinh doanh và để mọi thứ hoạt động, tất cả những gì còn lại là thêm chú thích org.springframework.kafka.annotation.KafkaListener , quen thuộc với tất cả các nhà phát triển Spring.

Nếu không thể xử lý thư sau tất cả các lần thử lại, thư sẽ chuyển đến DLT (chủ đề thư chết) bằng cách sử dụng Spring DeadLetterPublishingRecoverer. Theo yêu cầu hỗ trợ, chúng tôi đã mở rộng chức năng này và tạo một dịch vụ riêng cho phép bạn xem các tin nhắn có trong DLT, stackTrace, traceId và các thông tin hữu ích khác về chúng. Ngoài ra, tính năng giám sát và cảnh báo đã được thêm vào tất cả các chủ đề DLT và trên thực tế, giờ đây, sự xuất hiện của thông báo trong chủ đề DLT là lý do để phân tích và khắc phục lỗi. Điều này rất thuận tiện - theo tên của chủ đề, chúng tôi hiểu ngay vấn đề phát sinh ở bước nào của quy trình, điều này giúp tăng tốc đáng kể việc tìm kiếm nguyên nhân gốc rễ của nó.

“Đi trong đôi giày của tôi” - chờ đã, chúng có được đánh dấu không?

Gần đây nhất, chúng tôi đã triển khai một giao diện cho phép chúng tôi gửi lại tin nhắn bằng sự hỗ trợ của chúng tôi sau khi loại bỏ nguyên nhân của chúng (ví dụ: khôi phục chức năng của hệ thống bên ngoài) và tất nhiên là xác định lỗi tương ứng để phân tích. Đây là lúc các chủ đề tự thân của chúng tôi trở nên hữu ích: để không khởi động lại chuỗi xử lý dài, bạn có thể khởi động lại chuỗi đó từ bước mong muốn.

“Đi trong đôi giày của tôi” - chờ đã, chúng có được đánh dấu không?

Vận hành nền tảng

Nền tảng này đã hoạt động hiệu quả, hàng ngày chúng tôi thực hiện việc giao hàng và vận chuyển, kết nối các trung tâm phân phối và cửa hàng mới. Là một phần của chương trình thí điểm, hệ thống này hoạt động với các nhóm sản phẩm “Thuốc lá” và “Giày”.

Toàn bộ nhóm của chúng tôi tham gia tiến hành thí điểm, phân tích các vấn đề mới nổi và đưa ra đề xuất cải tiến sản phẩm của mình, từ cải thiện nhật ký đến thay đổi quy trình.

Để không lặp lại sai lầm của chúng tôi, tất cả các trường hợp được phát hiện trong quá trình thí điểm đều được phản ánh trong các thử nghiệm tự động. Sự hiện diện của một số lượng lớn các bài kiểm tra tự động và kiểm tra đơn vị cho phép bạn tiến hành kiểm tra hồi quy và cài đặt một hotfix theo đúng nghĩa đen trong vòng vài giờ.

Bây giờ chúng tôi tiếp tục phát triển và cải thiện nền tảng của mình và không ngừng đối mặt với những thách thức mới. Nếu bạn quan tâm, chúng tôi sẽ nói về các giải pháp của chúng tôi trong các bài viết sau.

Nguồn: www.habr.com

Thêm một lời nhận xét