thắc mắc Cách mà 1 server hoạt động

  • Người tạo chủ đề Người tạo chủ đề phuctienn
  • Ngày bắt đầu Ngày bắt đầu
Câu 1:
Tuỳ cách bạn xử lý, b có thể hiểu code chạy như 1 dây chuyền, có thể bốc thằng này ra xử lý xong đến thằng kia, cũng có thể bốc vài thằng 1, mặc dù tốc độ bốc ra nhanh(gần như tức thời) nhma về lí thuyết thì vẫn phải có thằng trước thằng sau, nhma vẫn có thể coi là có thể xử lý song song. Xử lý song song thì có multi threading, nghĩa là chạy thằng này 1 tí thằng kia 1 tí, hoặc 1 vài ngôn ngữ sẽ có cách xử lý riêng, nhma về cơ bản cách thức đều như t nói ở trên chạy thằng này 1 tí thằng kí 1 tí
Câu 2:
Phần lớn trường hợp thì đều ok, sql có vài loại có thể query được Autoincrement, b có thể query laấtIndex như trên, tuy nhiên nên để ý trường hợp sau khi b lấy ra, thì trước khi b thêm mới record request khác đã thêm được 1 record trước, làm cái Autoincrement đó sai(thấp hơn Autoincrement hiện tại), trong trường hợp đó b có thể lock table lại.

via theNEXTvoz for iPhone
 
Em chào các bác, em có các thắc mắc như sau mong các bác khai sáng cho em ạ

Câu hỏi 1:
- 2 máy cùng gọi đến 1 API. API này tốn 10s để thực hiện. Khi máy 1 vừa gọi API, máy 2 cũng gọi đến API đó, vậy máy 2 có phải đợi 10s để server trả xong kết quả cho máy 1 rồi mới thực hiện không. Nếu không thì server thực hiện chia thread hay như thế nào để có thể chạy song song trả kết quả về cho nhiều máy cùng lúc

Câu hỏi 2:
- Ví dụ 1 hàm thêm sản phẩm. Id của sản phẩm là tự động tăng. Để lấy Id vừa thêm thì ta phải lấy Id lớn nhất trong database. Vậy Id này có đúng không, trường hợp nhiều người thêm sản phẩm 1 lúc thì như thế nào (khi sản phẩm vừa được thêm vào db, cùng lúc đó nhiều sản phẩm khác của người dùng khác cũng được thêm vào db, vậy hàm lấy Id lớn nhất trong database có còn lấy được Id của sản phẩm vừa thêm không)

Hàm có dạng như dưới
C#:
Product InsertProduct(Product product) {
    _db.Products.Insert(product);
    var id = _db.Products.GetLastIndexInserted(); // Lấy Id mới nhất vừa được thêm
    product.Id = id;
    return product;
}
- Câu hỏi em thấy tương tự câu trên: Trong 1 hàm, gọi 2 lần hàm GetNewProducts để lấy danh sách sản phẩm mới nhất, 2 kết quả này có khác nhau không. Nếu giống nhau thì server thực hiện theo cơ chế nào
Mình đang làm các hệ thống như vầy đây.

Với câu hỏi 1 : Các server sẽ cho bạn thiết lập multi_thread : bao nhiêu thread, thì config ngay trong server. Ví dụ tomcat đi cho cụ thể :
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000"
maxThreads="25"
redirectPort="8443" />

Vậy mỗi request thì sẽ vô 1 thread, full 25 thread, thì chờ nhau thôi.
Hôm nọ mình có 1 case, server mình có 2 api (webservice). Lúc đó hệ thống bên kia bị đơ, 1 api bị time out liên tục, mà đang để timeout 60s, thế là đủ 50 kết nối, thì api2 bị đơ luôn. Nghĩ mãi mới ra là do , server đang config max 50 thread, nên khi api1 chiếm đủ 50 thread, thì api2 chỉ có biết ngồi cười. Phải tăng lên 200 thì api2 chạy phà phà.

Còn câu hỏi thứ 2. Thì bên mình sẽ dùng 1 cái nextVal. Sequence
insert into XXX (id, ...) values (seq_xxx.nextVal, ...)
Đầu tiên trước khi insert, ta gọi hàm nextVal, để lấy id của row bạn cần insert. Rồi insert = cái id đó. Thì lúc này đảm bảo có 1000 thằng insert vô cùng lúc thì vẫn lấy đúng id, của cái bạn vừa insert.

int id = abc.nextVal;
insert_into_db(id,col1,col2,col3...)
 
Câu 1:

Tùy vào trình code, nên tìm hiểu thêm về ThreadPool, Async Runtime. Cơ bản thì các framework hiện đại đều dùng 1 loại runtime dựa trên thread/green thread để phân bổ works/tasks vào resource tương ứng của máy. Một server code tốt, hardware OK thì với 8 threads cũng có thể phục vụ 1000 hay 10_000 rps, miễn là còn đủ resource. Bạn trên kia nói request per thread 1-1 là một công nghệ rất cũ, lỗi thời rồi giờ ko ai thiết kế như vậy cả, 1 request 1 thread thì bao nhiêu thread cho đủ :), mà càng nhiều thread càng chậm thôi chứ có nhanh hơn đc gì đâu.

Câu 2:

Tùy vào db của bạn là loại gì. Ví dụ Postgres thì là vầy:
 
Mình đang làm các hệ thống như vầy đây.

Với câu hỏi 1 : Các server sẽ cho bạn thiết lập multi_thread : bao nhiêu thread, thì config ngay trong server. Ví dụ tomcat đi cho cụ thể :
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000"
maxThreads="25"
redirectPort="8443" />

Vậy mỗi request thì sẽ vô 1 thread, full 25 thread, thì chờ nhau thôi.
Hôm nọ mình có 1 case, server mình có 2 api (webservice). Lúc đó hệ thống bên kia bị đơ, 1 api bị time out liên tục, mà đang để timeout 60s, thế là đủ 50 kết nối, thì api2 bị đơ luôn. Nghĩ mãi mới ra là do , server đang config max 50 thread, nên khi api1 chiếm đủ 50 thread, thì api2 chỉ có biết ngồi cười. Phải tăng lên 200 thì api2 chạy phà phà.

Còn câu hỏi thứ 2. Thì bên mình sẽ dùng 1 cái nextVal. Sequence
insert into XXX (id, ...) values (seq_xxx.nextVal, ...)
Đầu tiên trước khi insert, ta gọi hàm nextVal, để lấy id của row bạn cần insert. Rồi insert = cái id đó. Thì lúc này đảm bảo có 1000 thằng insert vô cùng lúc thì vẫn lấy đúng id, của cái bạn vừa insert.

int id = abc.nextVal;
insert_into_db(id,col1,col2,col3...)
Cả 2 câu trả lời của bạn đều quá lỗi thời. Cập nhật công nghệ đi bạn.

về thread thì có nói ở trên rồi, còn id thì cứ insert vào thôi đâu cần làm 2 lần, dùng AutoIncrement của Postgres nó đảm bảo cho bạn rồi.
 
Cả 2 câu trả lời của bạn đều quá lỗi thời. Cập nhật công nghệ đi bạn.

về thread thì có nói ở trên rồi, còn id thì cứ insert vào thôi đâu cần làm 2 lần, dùng AutoIncrement của Postgres nó đảm bảo cho bạn rồi.
Ý bạn kia muốn lấy id của row vừa insert mà. Trừ khi hàm insert của postgres có gì đặc biệt hơn.
 
Câu 1: Theo mình biết Spring MVC thì mỗi Servlet được maintain 1 thread để xử lý 1 HTTP request. Do vậy server có thể handle nhiều kết nối HTTP cùng lúc mà không cần phải chờ thằng này, hay thằng kia xong. Nhưng số lượng thread có thể spawn là giới hạn, khi tới limit, các request sẽ được đưa vào queue, thread nào xử lý xong lấy request ra khỏi queue và xử lý tiếp. Nên câu trả lời là có thể có, có thể không (tùy vào tình huống)

Câu 2: Chắc chắn lấy id lớn nhất không đảm bảo lấy ra sản phẩm vừa thêm. Đối với các SQL Server, mỗi câu query đều được handle bởi 1 thread (tương tự như trên, ở đây mình lấy MySQL làm ví dụ). Việc bạn get id lớn nhất ngay sau khi thêm không đảm bảo rằng giữa 2 lần truy vấn liên tiếp không có 1 thread khác thêm sản phẩm mới vào (có id lớn hơn). Nhưng vẫn có cách để ta có thể đảm bảo được bằng cách sử dụng lock (lock toàn bộ bản khi add sản phẩm mới). Chỉ khi nào bạn release lock thì các luồng khác mới có quyền write vào, lúc này bạn có thể get id lớn nhất rồi sau đấy nhả lock ra

Newbie, các bác nhẹ tay
ucheJZL.gif
 
Edit: hình như trả lời hơi lạc đề
cái fen ghi là hiểu đúng rồi đấy, do máy ko cài mysql nên ko tiện test nhưng hỏi chatGPT nó bảo nếu chưa insert cái gì mà chạy "Select LAST_INSERT_ID();" sẽ trả về 0
Cho nên để chạy được Select LAST_INSERT_ID(); thì phải chạy chung với câu insert trong 1 transaction nhé.
Vd trong mysql:
BEGIN TRANSACTION; // hoặc có thể set auto_commit=0
INSERT INTO test_table VALUES ("ten san pham","1000 ngan");
SELECT LAST_INSERT_ID(); // trả về ID của thằng trên
COMMIT;
Cái này thì phải tùy vào Isolation Level bác set cho DB nữa chứ nhỉ? Hay là Select Last_insert_id sẽ luôn đúng không phụ thuộc vào Isolation Level mà mình set?
 

Thống kê chủ đề

Ngày tạo
phuctienn,
Người trả lời cuối
seoitsystem,
Trả lời
49
Lượt xem
11.290
Quay lại
Lên đầu trang