Chào bạn. Cho mình hỏi làm sao để connect ssh với cái ec2 mình vừa tạo. Ví dụ mình muốn cài docker va docker compose, thì bắt buộc phải cài luôn trong file bash.sh à. Thanks.
Anh hiểu câu hỏi của em là sau khi order-service gửi event sang payment-service yêu cầu thanh toán, payment-service thực hiện business nhưng bị exception (app crash/lost connection to database....). Lúc này xảy ra tình huống mất message như em nói, trong khi expect next event SUCCESS/FAIL. Trường hợp này xử lý thế nào? Có đúng em định hỏi thế này không?
Em đọc bài trước của anh phần handle exception nhé. Vấn đề của em nói nó không phụ thuộc vào transaction outbox nữa mà nó là vđề của việc handle business exception. Có 2 cách: 1 là retry và 2 là cancel. Nhưng chung quy lại nó sẽ là vấn đề của việc event phải lưu ở đâu để đảm bảo k mất event, để khi exception xảy ra (app crash, lost connection...) thì hệ thống vẫn consume lại đc event đó để xử lý tiếp. Nên vấn đề sẽ chỉ còn là việc event được lưu ở đâu để đảm bảo 2 tính chất: ordering và durability.
Cái này thì nó lại là bài toán khác không liên quan đến Outbox. Nên mình sẽ quay về xử lý việc store event nhé, nếu là anh anh sẽ sử dụng Kafka làm message broker vì nó support việc replay message trong trường hợp exception. Em có thể đọc thêm series Kafka của a để hiểu rõ hơn. Đại khái là ở TH1 như em nói thì mấu chốt là cần consume lại chính event đó để retry -> đã đc giải quyết = Kafka.
Còn TH2 nếu em dùng transactionless thì việc rollback thế nào em phải handle = code. Em cần implement state machine hoặc một cách nào đó để lưu được state hiện tại của hệ thống, dựa trên đó em có rollback phù hợp. Nhưng anh thì không khuyến khích cách này.
@thinh24 Hướng dẫn thì bạn search trên mạng nhiều mà. Nhưng khuyến khích bạn nếu không chuyên thì nên nhờ đội làm Chatbot họ tích hợp luôn cho. Vì cũng cần phải chỉnh sửa cấu hình lúc deploy lại server Chatbot nữa.
@pham.van.toan mình muốn cài lên website, facebook, telegram. mà mình ko phải là dân chuyên nghiệp nên có hướng dẫn nào cài đặt lên website, facebook, telegram dễ dàng, đơn giản, dễ hiểu ko nhỉ?
Hello anh , cảm ơn anh về những chia sẻ rất hay về SAGA nhưng em muốn hỏi anh chút về Outbox ạ mong anh rep , hí hí
Trong bài toán của anh nếu là đến đoạn payment xử lý cắt tiền xong gửi msg cho order thì bị lỗi thì bên order ko nhận dc msg nên ko update dc status nên mình đã xử dụng outbox , chỗ này theo em chia làm 2 trường hợp
TH1 : hàm của anh có đánh transactional thì mà giả xử trong hàm đó xảy ra bất kì 1 lỗi throws exception nào thì nó không update status của payment dc và cũng ko lưu data xuống outbox để publish msg dc ạ -> cũng mất msg ( expect của mình ở đây là phải trả về msg FAILED )
TH2: hàm của anh không đánh transactional thì oke vấn đề ở TH1 dc giải quyết = cách try catch nó , nhưng vấn đề khi ko đánh transactional xảy ra đó là nó ko rollback data dc tại service payment . Nhưng thế thì cũng có cách tự rollback thủ công nhưng vấn đề em băn khoăn ở đây là nó đã save data xuống những bảng nào để mình có thể rollback ạ , ví dụ em có đoạn code sau trong 1 function ạ
dòng 1 : xảy ra exception
dòng 2 : save data vào database table payment entity
ở đây mình có thể trycatch để gửi lại msg FAILED cho order nhưng mình cũng phải biết nó đã save ở đâu mà còn rollback anh ạ nếu bên payment service vẫn lắng nghe msg FAIL từ order service gửi lại để rollback thì em nghĩ có vẻ sẽ xảy ra lỗi khi mà thực sự data chưa dc save vào table payment mà mình vẫn cứ update thì ko hợp lý lắm
Vấn đề của em cũng hơi dài rồi , cảm ơn anh và mong anh rep ạ
Khi test method PUT thì bị lỗi thiếu tham số id, vì trong code, hàm cập nhật (PUT method) sử dụng đầu vào là @PathVariable(value = "id") nên chỗ annotation
@RequestMapping(value = "/contact/", method = RequestMethod.PUT) phải sửa thành @RequestMapping(value = "/contact/{id}", method = RequestMethod.PUT) , value như hàm lấy một contact thì mới chạy được. Cách khác các bạn có thể sửa t@PathVariable(value = "id") thành @RequestParam(value = "id"). Sau đó khi test các bạn chọn tab params và thêm entry có key là "id" và value là "<id contact bạn muốn sửa>" lúc đó path sẽ dạng như thế này: "api/contact/?id=7". Một cách nữa là bỏ tham số đầu vào id nhưng khi nhận một contact từ client dạng body trong đó có thể nhận thộc tính id thì ta sẽ lấy id đó để nhận diện được là sửa contact nào như vậy code bên trong hàm method PUT sẽ cần lấy id từ cái body ra (thêm mới 1 dòng: "long id = contactForm.getId();" sau đó sửa dòng "Contact contact = contactService.getOne(contactId);" thành "Contact contact = contactService.getOne(id);" sẽ chạy được.
Các method còn lại thì làm theo hướng dẫn video mình để link ở trên thì vẫn chạy bình thường.
bạn có thể chọn mount tất cả ở docker-compose nhưng như thế thì trong container của bạn sẽ nhiều thứ, nặng, ko cần thiết. Thay vào đó ta nên linh hoạt, các thành phần nào cần thiết để chạy được appp thì nên để ở Dockerfile với COPY/ADDD (source code chẳng hạn), còn các thành phần mà bạn muốn giữ/lưu lại (persist) kể cả khi container bị khởi động lại thì ta cho vào volume (ví dụ: ảnh, file,....)
THẢO LUẬN
bài viết khá ok bạn ạ
!otherArr.includes(v) nếu bằng true thì thực hiện câu lên bên phải && ngược lại thì không nha bn
bạn xem bài 12 nhé
Cảm ơn chia sẻ rất chi tiết của bạn
Chào bạn. Cho mình hỏi làm sao để connect ssh với cái ec2 mình vừa tạo. Ví dụ mình muốn cài docker va docker compose, thì bắt buộc phải cài luôn trong file bash.sh à. Thanks.
Anh ơi anh có thể ra 1 bài viết phân tích sự khác nhau giữa Stream và Thread ko?
Uầy vừa giải thích đơn giản vừa hay ho, đỉnhhhhhh quá anh ơi
@datbv Em cảm ơn anh em đã hiểu rồi ạ !
hi em,
Anh hiểu câu hỏi của em là sau khi order-service gửi event sang payment-service yêu cầu thanh toán, payment-service thực hiện business nhưng bị exception (app crash/lost connection to database....). Lúc này xảy ra tình huống mất message như em nói, trong khi expect next event SUCCESS/FAIL. Trường hợp này xử lý thế nào? Có đúng em định hỏi thế này không?
Em đọc bài trước của anh phần handle exception nhé. Vấn đề của em nói nó không phụ thuộc vào transaction outbox nữa mà nó là vđề của việc handle business exception. Có 2 cách: 1 là retry và 2 là cancel. Nhưng chung quy lại nó sẽ là vấn đề của việc event phải lưu ở đâu để đảm bảo k mất event, để khi exception xảy ra (app crash, lost connection...) thì hệ thống vẫn consume lại đc event đó để xử lý tiếp. Nên vấn đề sẽ chỉ còn là việc event được lưu ở đâu để đảm bảo 2 tính chất: ordering và durability.
Cái này thì nó lại là bài toán khác không liên quan đến Outbox. Nên mình sẽ quay về xử lý việc store event nhé, nếu là anh anh sẽ sử dụng Kafka làm message broker vì nó support việc replay message trong trường hợp exception. Em có thể đọc thêm series Kafka của a để hiểu rõ hơn. Đại khái là ở TH1 như em nói thì mấu chốt là cần consume lại chính event đó để retry -> đã đc giải quyết = Kafka.
Còn TH2 nếu em dùng transactionless thì việc rollback thế nào em phải handle = code. Em cần implement state machine hoặc một cách nào đó để lưu được state hiện tại của hệ thống, dựa trên đó em có rollback phù hợp. Nhưng anh thì không khuyến khích cách này.
@pham.van.toan vậy à. dù sao cũng cảm ơn bạn
@thinh24 Hướng dẫn thì bạn search trên mạng nhiều mà. Nhưng khuyến khích bạn nếu không chuyên thì nên nhờ đội làm Chatbot họ tích hợp luôn cho. Vì cũng cần phải chỉnh sửa cấu hình lúc deploy lại server Chatbot nữa.
bài viết rất hay và dễ hiểu ạ, tks chủ thớt
Thank you
@pham.van.toan mình muốn cài lên website, facebook, telegram. mà mình ko phải là dân chuyên nghiệp nên có hướng dẫn nào cài đặt lên website, facebook, telegram dễ dàng, đơn giản, dễ hiểu ko nhỉ?
Bài viết rất hay! Thank b
Hello anh , cảm ơn anh về những chia sẻ rất hay về SAGA nhưng em muốn hỏi anh chút về Outbox ạ mong anh rep , hí hí
không chạy được @_@
Các bạn có thể xem hướng dẫn test các phương thức còn lại ở nguồn dưới: https://www.youtube.com/watch?v=fsWEqTa_MGg
Lưu ý:
Khi test method POST thì phải sửa annotation @GeneratedValue(strategy=GenerationType.AUTO) thành @GeneratedValue(strategy = GenerationType.IDENTITY) link tham khảo fix (https://stackoverflow.com/questions/49813666/table-dbname-hibernate-sequence-doesnt-exist)
Khi test method PUT thì bị lỗi thiếu tham số id, vì trong code, hàm cập nhật (PUT method) sử dụng đầu vào là @PathVariable(value = "id") nên chỗ annotation @RequestMapping(value = "/contact/", method = RequestMethod.PUT) phải sửa thành @RequestMapping(value = "/contact/{id}", method = RequestMethod.PUT) , value như hàm lấy một contact thì mới chạy được. Cách khác các bạn có thể sửa t@PathVariable(value = "id") thành @RequestParam(value = "id"). Sau đó khi test các bạn chọn tab params và thêm entry có key là "id" và value là "<id contact bạn muốn sửa>" lúc đó path sẽ dạng như thế này: "api/contact/?id=7". Một cách nữa là bỏ tham số đầu vào id nhưng khi nhận một contact từ client dạng body trong đó có thể nhận thộc tính id thì ta sẽ lấy id đó để nhận diện được là sửa contact nào như vậy code bên trong hàm method PUT sẽ cần lấy id từ cái body ra (thêm mới 1 dòng: "long id = contactForm.getId();" sau đó sửa dòng "Contact contact = contactService.getOne(contactId);" thành "Contact contact = contactService.getOne(id);" sẽ chạy được.
Các method còn lại thì làm theo hướng dẫn video mình để link ở trên thì vẫn chạy bình thường.
Chúc các bạn code vui vẻ.
thanks
@5ting4U nó tuỳ nhé bạn,
bạn có thể chọn mount tất cả ở docker-compose nhưng như thế thì trong container của bạn sẽ nhiều thứ, nặng, ko cần thiết. Thay vào đó ta nên linh hoạt, các thành phần nào cần thiết để chạy được appp thì nên để ở Dockerfile với COPY/ADDD (source code chẳng hạn), còn các thành phần mà bạn muốn giữ/lưu lại (persist) kể cả khi container bị khởi động lại thì ta cho vào volume (ví dụ: ảnh, file,....)