Làm cách nào để thiết kế các dịch vụ web có khả năng mở rộng cao trong Java?


15

Tôi đang tạo một số Dịch vụ web có 2000 người dùng đồng thời. Các dịch vụ được cung cấp miễn phí và do đó dự kiến ​​sẽ có được một lượng lớn người dùng. Trong tương lai, nó có thể được yêu cầu mở rộng tới 50.000 người dùng.

Đã có một vài câu hỏi khác giải quyết vấn đề như - /programming/2567254/building-highly-scalable-web-service

Tuy nhiên yêu cầu của tôi khác với câu hỏi trên.

Ví dụ: Ứng dụng của tôi không có giao diện người dùng, vì vậy hình ảnh, CSS, javascript không phải là vấn đề. Đó là trong Java nên các đề xuất như sử dụng HipHop để dịch PHP sang mã gốc là vô ích.

Do đó tôi quyết định hỏi riêng câu hỏi của mình.

Đây là thiết lập dự án của tôi -

  1. Phần còn lại dựa trên các dịch vụ Web bằng Apache CXF
  2. Hibernate 3.0 (Với các tối ưu hóa có liên quan như tải lười biếng và HQL tùy chỉnh để điều chỉnh)
  3. Mèo Tom 6.0
  4. MySql 5.5

Các thực tiễn tốt nhất cần tuân thủ để làm cho ứng dụng dựa trên Java có thể mở rộng là gì?


Nếu bạn đang phơi bày một dịch vụ REST, sử dụng proxy ngược như Varnish sẽ giúp ích rất nhiều. Làm thế nào mới dữ liệu cần phải được? Bạn có chắc chắn cần một cơ sở dữ liệu quan hệ? Bạn có thể phân vùng dữ liệu? Với ngăn xếp công nghệ mà bạn đang mô tả, tôi sẽ tập trung vào việc đảm bảo càng ít yêu cầu càng tốt thực sự đạt đến điểm cuối của bạn. Bạn đã xem xét việc thực hiện bộ nhớ này với các giải pháp như Hazel cast / Gigaspaces, v.v.?
ebaxt

@ebaxt cảm ơn bạn đã góp ý. Gigaspaces dường như là nguồn mở. Nhưng dàn diễn viên Hazel có vẻ thú vị.
Kshitiz Sharma

1
@ebaxt "Bạn có chắc bạn cần một cơ sở dữ liệu quan hệ?" Việc chấp nhận nosql sẽ có những thay đổi mạnh mẽ về kiến ​​trúc ứng dụng. Chúng tôi đang cố gắng giữ sự phức tạp đến mức tối thiểu. Chi phí mặc dù không phải là một yếu tố cho chúng tôi. Vì vậy, chúng tôi sẽ gắn bó với phương pháp quan hệ.
Kshitiz Sharma

1
Bạn có thể sử dụng Postgres, MySQL hoặc những gì đã từng. Cơ sở hạ tầng của bạn là gì? Bạn có thể sử dụng mảng đĩa? Là các máy chủ được lưu trữ trong cùng một vị trí? Bạn có thể kết nối cụm của bạn với nhịp tim, vv? Bạn có thể đặt chúng trong cùng một mạng con?
phù

1
Tôi cũng là một lập trình viên. Nhưng nếu cơ sở dữ liệu quan hệ của bạn là nút cổ chai, bạn sẽ có xu hướng kết thúc với câu hỏi này. Có một số cơ sở dữ liệu trên thị trường một số hoạt động tốt hơn so với khác trong một số tình huống. Nhưng họ đang sử dụng các Mức cô lập giao dịch mặc định khác nhau và Đồng thời lạc quan so với Đồng thời bi quan, v.v.
edze

Câu trả lời:


8

Tôi đã xử lý vấn đề này trong quá khứ, nhưng vẫn cảm thấy mình có nhiều điều để học hỏi trên sân. Tôi thấy đây là một trong những lĩnh vực thú vị nhất hiện nay trong phát triển phần mềm, đây là một số suy nghĩ về điều này:
MySQL là cơ sở dữ liệu đủ công bằng trừ khi bạn làm việc với lượng dữ liệu khổng lồ và trong trường hợp này bạn có thể xem xét NoQuery cơ sở dữ liệu, nhưng bạn nên kiểm tra cẩn thận cơ sở dữ liệu NoQuery tốt nhất cho nhu cầu của bạn là gì .

Bạn nên triển khai bộ đệm ẩn trong hệ thống của mình - cố gắng lưu trữ càng nhiều dữ liệu chỉ đọc càng tốt hoặc xác định một số chiến lược lưu trữ - ví dụ: chúng tôi có một kịch bản trong đó người dùng thấy "dữ liệu cũ" là hợp lệ miễn là bản cập nhật gần đây diễn ra trong giờ qua.
Tôi sẽ xem xét JBoss Cache, hoặc có thể là Infinispan (giống như cấu trúc dữ liệu phân tán) hoặc khung bộ đệm phổ biến khác cho việc này.
Ngoài ra, như bạn đã đề cập đến tomcat, tôi giả sử bạn làm việc trong một số mô-đun yêu cầu đáp ứng. Hãy thử xem xét sử dụng bộ đệm tồn tại trong phạm vi của một yêu cầu nhất định, đây có thể là một HashMap đơn giản được liên kết với bộ lưu trữ cục bộ của luồng .
Ý tưởng của tôi ở đây khá giống với bộ đệm cấp đầu tiên tại Hibernate .

Bạn nên nhớ rằng các tệp, giao dịch và các tài nguyên khác rất tốn kém về việc giữ cho chúng mở. Đảm bảo bạn đóng các tệp và giao dịch càng sớm càng tốt, nếu không bạn sẽ gặp phải các lỗi sẽ tái tạo trên các thiết lập quy mô lớn

Ngoài ra, bạn phải hiểu 2000 người dùng đồng thời - điều này có nghĩa là 2000 người dùng đang truy cập máy chủ của bạn cùng một lúc hay họ đang sử dụng hệ thống của bạn? Phân biệt giữa các trường hợp 2000 người dùng cố gắng mở một ổ cắm cho máy chủ của bạn và trường hợp chỉ có 500 và 1500 hiện đang xem kết quả, về việc điền thông tin vào phía máy khách.

Bạn nên cân nhắc sử dụng phân cụm - bạn sẽ phải xử lý các vấn đề như có thể cải thiện mọi thứ, vì hầu hết quyền truy cập chỉ ở chế độ đọc. Cân nhắc việc lưu trữ và xác thực bộ đệm phía máy khách nếu có thể, cố gắng lưu các cuộc gọi đến máy chủ và chỉ gửi các khác biệt về dữ liệu, trong trường hợp hầu hết phản hồi của bạn cho một yêu cầu có cùng tham số không thay đổi. Ví dụ: tại cân bằng tải , phiên dính (có nghĩa là bộ cân bằng tải sẽ chuyển hướng một yêu cầu đến cùng một máy chủ cho cùng một phiên) và hơn thế nữa.

Nếu bạn cần phải có mã đồng bộ hóa - hãy chọn chiến lược đồng bộ hóa một cách cẩn thận. Tôi đã thấy một số hệ thống sử dụng khóa đơn giản, nhưng ReaderWriterLock


dự án nguồn mở oVirt, chúng tôi yêu cầu lấy số liệu thống kê của một máy ảo cụ thể. một số dữ liệu của VM hiếm khi thay đổi, vì vậy chúng tôi chỉ gửi MD5 của nó, nếu dữ liệu thay đổi giá trị MD5 cũng bị thay đổi, chúng tôi thực hiện yêu cầu lấy dữ liệu đầy đủ, chứ không chỉ MD5.

Tôi đã đề cập đến hibernate trước đây - tôi sẽ giới thiệu lại cho bạn xem xét cẩn thận việc sử dụng nó - nếu bạn cần thực hiện nhiều bài viết và ít đọc hơn, Hibernate có thể không lý tưởng cho bạn và bạn nên xem xét có thể làm việc với Spring-JDBC như một trình bao bọc JDBC. (không truy cập cùng một lúc về việc mở 2000 socket vào máy chủ của chúng tôi), nhưng sử dụng / duyệt hệ thống của chúng tôi, sử dụng JBoss Cache và tải trước vào bộ đệm một số dữ liệu được truy cập nhiều nhất hoặc dữ liệu chúng tôi nhận ra sẽ "nóng và phổ biến "Nhưng giải pháp của chúng tôi là tốt cho kiến ​​trúc và dòng chảy của chúng tôi, vì vậy như tôi nói trong những trường hợp này - Có nhiều mẹo và thủ thuật hơn, nhưng nó thực sự phụ thuộc vào kiến ​​trúc của bạn và dòng chảy bạn cần có trong hệ thống của bạn. Chúc may mắn!

Lập chỉ mục cơ sở dữ liệu của bạn một cách khôn ngoan và sử dụng một lược đồ db chính xác. Cân nhắc sử dụng một lớp các thủ tục được lưu trữ khi chúng được biên dịch trước và tối ưu hóa

Tôi muốn nói rằng trước đây, tôi đã xử lý một hệ thống (nút đơn) trên mysql (chủ yếu là truy cập chỉ đọc) với jboss 4.2.1 và được quản lý để đạt 2000 đồng thời người dùng



Tôi đồng ý ngoại trừ các procs được lưu trữ, không sử dụng các procs được lưu trữ. Và bạn có thể sử dụng hàm băm và giá trị nguyên tử đồng thời, để tạo luồng an toàn
NimChimpsky

3

Câu hỏi hay. Có lẽ khó có thể nói đó là cách tiếp cận tốt nhất, nhưng sẽ thử từ kinh nghiệm của tôi.

Cách tốt nhất để mở rộng ứng dụng web dựa trên Java là viết nó càng phi trạng thái càng tốt (nếu bạn có thể). Điều này cho phép bạn mở rộng quy mô ứng dụng theo chiều ngang, nơi bạn có thể thêm máy chủ tomcat nếu có nhiều người dùng đồng thời hơn.

Tuy nhiên, như bạn đã lưu ý, có thể có vấn đề với các kết nối cơ sở dữ liệu. Nhưng câu hỏi tôi có là, làm thế nào bạn có được dữ liệu? Là người dùng tạo ra hoặc bạn nhận được dữ liệu từ bên thứ ba? Điều này rất quan trọng bởi vì, nếu bạn đang cung cấp dịch vụ cho người dùng của mình với dữ liệu được tổng hợp từ ứng dụng của bên thứ ba (giả sử FB, Twitter, v.v.), thì những gì bạn có thể làm theo, là ghi vào cơ sở dữ liệu và sao chép dữ liệu sang cơ sở dữ liệu nô lệ được phân bổ cho từng trường hợp tomcat. Sau đó, mỗi máy chủ tomcat có thể nhận được từ cơ sở dữ liệu nô lệ của riêng mình.

 Are there faster alternatives to Mysql?

Bạn có thể đi đến cụm MySQL có kho dữ liệu trong bộ nhớ. Nhưng hãy cẩn thận với thực tế là ứng dụng có thể cần một số thay đổi. Không sql joinsđược hỗ trợ tốt trong cụm MySQL mặc dù trong phiên bản mới nhất có những cải tiến tương tự. Nếu chi phí không phải là một yếu tố, thì bạn có thể thử Oracle.

Các giải pháp bộ nhớ đệm chắc chắn sẽ cải thiện hiệu suất. Nhưng sau đó, tất cả phụ thuộc vào kiến ​​trúc của toàn bộ ứng dụng. Bạn nên biết rõ khi nào nên đẩy dữ liệu vào bộ đệm, khi nào nên làm bẩn (xóa khỏi bộ đệm).

Về việc phân phối tải trong môi trường nhiều máy chủ, tôi khuyên bạn nên sử dụng cân bằng tải hơn là sử dụng Apache để cân bằng tải.


"Tôi sẽ đề nghị bạn sử dụng bộ cân bằng tải hơn là sử dụng Apache để cân bằng tải" Bạn sẽ đề xuất phương pháp / phần mềm nào nếu không phải là Apache?
Kshitiz Sharma

Về cơ bản, tôi đã khuyến nghị phần cứng cân bằng tải, mà quản trị viên mạng của bạn sẽ có thể định cấu hình. Chương trình này có thêm chi phí cho dự án. Bộ cân bằng tải này sẽ có IP riêng (còn gọi là IP ảo) và về cơ bản, bạn sẽ gán IP này cho miền của mình. Khi yêu cầu đến, điều này sẽ định tuyến nó đến tất cả các máy chủ được kết nối theo kiểu vòng tròn (cũng là các thuật toán khác có sẵn). Bạn có thể sử dụng apache cho mục đích này nếu phần cứng không phải là một tùy chọn, nhưng tôi thích phần cứng hơn vì bạn không cần điều chỉnh apache cho mục đích này.

Chúng tôi đang sử dụng một máy chủ chuyên dụng với httpd để làm điều tương tự. Phần cứng không phải là một vấn đề.
Kshitiz Sharma

Bạn có thể sử dụng httpd và mod_cluster, nếu tôi nhớ chính xác. Tôi sẽ cân nhắc cẩn thận trước khi đi đến giải pháp "quá mức" của LB phần cứng, trước khi kiểm tra httpd và mod_cluster

@zaske - Có lẽ bạn đã đúng khi cân bằng tải phần cứng có thể là quá mức cần thiết. Nhưng trong trường hợp bạn cần mở rộng quy mô, thật dễ dàng để làm bằng cách thêm nhiều máy chủ.

2

Tôi hiện đang thiết lập một hệ thống tương tự (ở cấp độ chuyên nghiệp) và đây là thiết kế tôi đã chọn:

  • Hai bộ cân bằng Nginx (cả hoạt động, cả chuyển đổi dự phòng cho cái kia, cân bằng với vòng tròn DNS)
  • Hai cơ sở dữ liệu MySQL trong chế độ sao chép chính chủ
  • Hai trường hợp Tomcat như một cụm tomcat
  • Hai phiên bản Memcached cho cả bộ nhớ đệm và chia sẻ trạng thái phiên cho cụm Tomcat

Điều này sẽ đạt được một giải pháp dự phòng, có tính sẵn sàng cao, có thể mở rộng.

Các bộ cân bằng tải (trên phần cứng tốt) sẽ dễ dàng cân bằng một dòng 1gbit bão hòa mỗi dòng. Đây cũng là một nơi tuyệt vời để giảm tải SSL.

Bạn có thể lưu thông tin phiên của bạn trong memcached. Trong trường hợp một trường hợp tomcat không thành công, một phiên bản tomcat khác có thể truy xuất thông tin phiên có liên quan và khách hàng sẽ không nhận thấy điều gì. Đừng quên kết hợp điều này với các phiên dính quá. (Để giảm lưu lượng mạng)

Phân cụm Tomcat cũng có một tùy chọn để chia sẻ thông tin phiên giữa các cụm trong thời gian thực mà không cần sử dụng memcached. Mặc dù tôi nghĩ hiệu suất là khôn ngoan, sử dụng Memcached sẽ tốt hơn.

Nếu bạn cần thêm năng lượng trong bất kỳ ứng dụng nào sau đây:

  • Nginx: Thêm nhiều bộ cân bằng tải hơn, mặc dù tôi không nghĩ rằng đây sẽ là nút cổ chai rất sớm.
  • Tomcat: bạn có thể dễ dàng tăng kích thước của cụm Tomcat hoặc thêm nhiều cụm
  • Mysql: Thêm một số nô lệ chỉ đọc hoặc tăng kích thước cụm (tùy thuộc vào ứng dụng của bạn, nhưng vì bạn đã viết một ứng dụng dựa trên REST, nên điều này không thành vấn đề)
  • Tôi tin rằng Memcached: Thêm nhiều nút hơn, quy mô Memcached khá tốt.

Tôi không biết ứng dụng của bạn được xây dựng như thế nào và nguồn tài nguyên lớn là gì, nhưng nếu bạn thấy tải cơ sở dữ liệu cao (trong quá trình tải của bạn!), Việc thêm bộ đệm giữa ứng dụng và cơ sở dữ liệu chắc chắn có thể cải thiện hiệu năng rất nhiều. Nhưng đừng quên rằng không phải mọi thứ đều có thể lưu trong bộ nhớ cache, nếu các truy vấn của bạn luôn khác nhau, bộ nhớ đệm sẽ không giúp ích (nhiều)

Lời khuyên của tôi là tải xuống VMware Workbench (hoặc phần mềm ảo hóa similair) và cố gắng tạo một thiết lập đơn giản. Không cân bằng tải hoặc phân cụm, chỉ là những điều cơ bản và làm việc từ đó. Từng người một thêm nhiều tính năng (cân bằng, lưu trữ, phân cụm, v.v.) và đảm bảo thực hiện một số nghiên cứu về từng chủ đề, vì vậy bạn sẽ biết bạn đã chọn đúng.

Nếu bạn tiếp tục chạy các bài kiểm tra hiệu suất tương tự trong quá trình này, bạn có thể tự mình xem nếu sử dụng X tốt hơn so với sử dụng Y trong thiết lập của bạn, hoặc bộ nhớ đệm tác động sẽ có gì, v.v.

Cuối cùng, một thiết lập như thế này thực sự phụ thuộc vào yêu cầu của ứng dụng và ứng dụng khách của bạn, mọi thứ có thể được thực hiện theo nhiều cách khác nhau, mỗi cách đều có điểm mạnh và điểm yếu riêng.

Còn câu hỏi nào nữa không?

Chúc may mắn!

Wesley


màu hạt dẻ? hazelcast.com
NimChimpsky

Bạn có sử dụng một khung công tác cho lớp bộ đệm không, hoặc chỉ một bó băm thủ công trên các truy vấn SQL?
djechlin
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.