CFSDN nhấn mạnh vào giá trị tạo ra nguồn mở và chúng tôi cam kết xây dựng nền tảng chia sẻ tài nguyên để mọi nhân viên CNTT có thể tìm thấy thế giới tuyệt vời của bạn tại đây.
Bài viết trên blog CFSDN SpringCloud OpenFeign Post yêu cầu giải pháp khắc phục lỗi 400 được tác giả sưu tầm và biên soạn. Nếu bạn quan tâm đến bài viết này thì nhớ like nhé.
Trong quá trình phát triển vi dịch vụ, nhóm gia đình SpringCloud tích hợp OpenFeign để gọi dịch vụ OpenFeign của SpringCloud sử dụng SpringMVCContract để phân tích định nghĩa giao diện của OpenFeign. Tuy nhiên, có một cạm bẫy lớn trong quá trình triển khai phân tích cú pháp giao diện Post của SpringMVCContract. Đó là, nếu bạn sử dụng yêu cầu Post với các tham số @RequestParam, thì các tham số sẽ được gắn trực tiếp vào URL.
Phát hiện và phân tích vấn đề.
Gần đây, các máy chủ trực tuyến đột nhiên và thường xuyên gặp phải cảnh báo tải CPU cao. Sau khi điều tra, người ta phát hiện ra rằng một số lượng lớn các lệnh gọi dịch vụ chéo OpenFeign trong nhật ký có 400 lỗi (Trạng thái HTTP 400).
Nhìn chung có hai tình huống:
- nginx trả về 400
- ứng dụng java trả về 400
Qua phân tích, người ta thấy rằng 400 được ứng dụng java trả về, do đó có thể xác định rằng đã xảy ra ngoại lệ khi máy khách OpenFeign bắt đầu một yêu cầu dịch vụ chéo. Tuy nhiên, sau khi kiểm tra mã nguồn, tôi thấy rằng giao diện dịch vụ xảy ra sự cố này rất đơn giản. Đó là giao diện yêu cầu POST chỉ có ba tham số. Lỗi này không phải là lỗi bắt buộc mà chỉ xảy ra khi giá trị tham số. tương đối dài (Chuỗi). Vì vậy, bước đầu có thể khẳng định rằng yêu cầu 400 có thể do các tham số quá dài gây ra. Tôi rất bối rối về lỗi 400 do các tham số quá dài trong yêu cầu POST bị treo. không nên xuất hiện 400.
Khắc phục sự cố.
Để xác minh dự đoán trên, tôi đã viết tay một ví dụ đơn giản và đặc biệt bật nhật ký gỡ lỗi của OpenFeign trong quá trình xác minh.
Đầu tiên viết giao diện dịch vụ.
Đây là giao diện Post đơn giản chỉ có một tham số (code ở đây chỉ dùng để xác minh, code không chính thức).
?
1
2
3
4
5
|
@FeignClient
(tên =
"người dùng-nhà cung cấp-dịch vụ"
)
công cộng
giao diện
Xin chàoDịch vụ {
@PostMapping
(
"/Xin chào"
)
công cộng
Chuỗi xin chào(
@Yêu cầuParam
(
"tên"
) Tên chuỗi);
}
|
Dịch vụ viết bài.
Chỉ cần viết giao diện Http cho dịch vụ (giống như trên, code chỉ dùng để xác minh).
?
1
2
3
4
5
6
7
8
9
10
11
12
|
@SpringBootỨng dụng
@Bộ điều khiển nghỉ ngơi
công cộng
lớp học
Người khởi đầu {
@Yêu cầu lập bản đồ
(
"/Xin chào"
)
công cộng
Chuỗi hello(Tên chuỗi) {
trở lại
"Giá trị trả về của dịch vụ người dùng: Xin chào"
+ String.valueOf(tên);
}
công cộng
tĩnh
vô hiệu
main(String[] args) {
SpringApplication.run(Người khởi tạo.
lớp học
, đối số);
}
}
|
Dịch vụ được đăng ký và gọi.
Đăng ký dịch vụ đến trung tâm đăng ký bằng cách gọi tới dịch vụ hello.
?
1
2
3
4
5
6
|
@Autowired
công cộng
Dịch vụ HelloService;
@Yêu cầu lập bản đồ
(
"/Xin chào"
)
công cộng
Chuỗi hello(Tên chuỗi) {
trở lại
helloService.hello(tên);
}
|
Có thể tìm thấy từ nhật ký rằng yêu cầu POST của Spring Cloud tích hợp OpenFeign trực tiếp treo các tham số trên URL, như hiển thị bên dưới:

Chính vì hố lớn này mà máy chủ trực tuyến thường xuyên gây ra cảnh báo tải CPU cao.
Vấn đề đã được giải quyết.
Bây giờ vấn đề đã được biết, thật dễ dàng để giải quyết. Theo tuyên bố chính thức của SpringCloud, bạn có thể sử dụng @RequestBody để giải quyết vấn đề này, nhưng việc sử dụng @RequestBody bị hạn chế, nghĩa là chỉ có thể có một tham số và toàn bộ liên kết cuộc gọi cần phải có Chi phí thực hiện các điều chỉnh tương ứng hơi cao. Chúng tôi không sử dụng phương pháp này ở đây mà sử dụngRequestInterceptor để xử lý nó.
Viết Yêu cầuInterceptor.
Ở đây, queryLine của yêu cầu được loại bỏ và đặt vào phần thân. Cần lưu ý rằng điều này chỉ có thể được thực hiện khi phần thân không có giá trị.
?
1
2
3
4
5
6
7
8
9
10
11
12
13
|
công cộng
lớp học
PostRequestInterceptor
thực hiện
Yêu cầu chặn {
@Ghi đè
công cộng
vô hiệu
áp dụng(mẫu RequestTemplate) {
nếu như
(
"bưu kiện"
.equalsIgnoreCase(template.method()) && template.body() ==
vô giá trị
) {
Chuỗi truy vấn = template.queryLine();
mẫu.queries(
mới
Bản đồ băm<>());
nếu như
(StringUtils.hasText(truy vấn) && truy vấn.startsWith(
"?"
)) {
template.body(query.substring(
1
));
}
mẫu.tiêu đề(
"Loại nội dung"
,
"ứng dụng/x-www-form-urlencoded;charset=UTF-8"
);
}
}
}
|
Định cấu hình Yêu cầu đánh chặn.
giả vờ: máy khách: cấu hình: mặc định: requestInterceptors: cn.com.ava.yaolin.springcloud.demo.PostRequestInterceptor 。
Như bạn có thể thấy trong hình bên dưới, các tham số yêu cầu không còn được gắn vào URL nữa.

Giải pháp của @RequestBody.
Mặc dù vấn đề đã được giải quyết nhưng đây không phải là giải pháp được đề xuất chính thức. Giải pháp @RequestBody được đề xuất chính thức cũng được đăng ở đây. Sử dụng @RequestBody để giải quyết, yêu cầu 4 bước:
Viết một tham số yêu cầu.
?
1
2
3
4
5
6
7
8
9
|
công cộng
lớp học
Xin chàoReqForm {
riêng tư
Tên chuỗi;
công cộng
Chuỗi getName() {
trở lại
tên;
}
công cộng
vô hiệu
setName(Tên chuỗi) {
cái này
.name = tên;
}
}
|
Điều chỉnh khai báo giao diện.
@PostMapping("/hello") public String hello(@RequestBody HelloReqForm biểu mẫu),
Điều chỉnh các cuộc gọi dịch vụ.
Biểu mẫu HelloReqForm = new HelloReqForm(); biểu mẫu.setName(tên); trả về helloService.hello(biểu mẫu),
Điều chỉnh việc triển khai dịch vụ.
@RequestMapping("/hello") public String hello(@RequestBody HelloReqForm form) { } 。
Nhật ký cuộc gọi cuối cùng.

Các lớp Java có liên quan.
Cuối cùng, liệt kê một số lớp java có liên quan:
- Giao diện dịch vụ SpringMVCContract
- Tham số requestParamParameterProcessor
- feign.RequestTemplate Trình tạo yêu cầu còn lại
- feign.Request xử lý các yêu cầu http
Trên đây là toàn bộ nội dung bài viết này hi vọng nó sẽ giúp ích cho việc học của mọi người và cũng mong mọi người ủng hộ mình.
Liên kết gốc: http://www.manongjc.com/detail/19-fxjynmrashzgysy.html.
Cuối cùng, bài viết này về giải pháp lỗi 400 yêu cầu SpringCloud OpenFeign Post kết thúc tại đây. Nếu bạn muốn biết thêm về giải pháp lỗi 400 yêu cầu SpringCloud OpenFeign Post, vui lòng tìm kiếm bài viết CFSDN hoặc tiếp tục duyệt các bài viết liên quan. trong tương lai! .
Tôi là một lập trình viên xuất sắc, rất giỏi!