Everywhere to OpenStack: Entropy affect java tomcat application startup time

Môi trường

  • Các ứng dụng Tomcat bên mình đang chạy Java 7, một số chạy Java 8
  • OS: CentOS 7
  • Ảo hóa: KVM (OpenStack Cloud)

Entropy là một thành phần trong hệ thống mà ít được anh em developer khi để ý. Entropy là một khái niệm chung để nói về sự ngẫu nhiên hay hỗn độn, càng nhiều "entropy" thì mọi thứ càng ngẫu nhiên.

Source: https://www.influxdata.com

Đối với các hệ thống máy tính, sự ngẫu nhiên của entropy được ứng dụng cho nhiều bài toán, đặc biệt là cho các hành động hay trao đổi liên quan đến bảo mật mà cần tính ngẫu nhiên để tránh bị theo dõi và đánh cắp dữ liệu. Entropy trong Linux đại diện cho số lượng số ngẫu nhiên mà hệ điều hành có thể cung cấp. Ban đầu, để đạt được tính ngẫu nhiên, các số ngẫu nhiên trong entropy được sinh ra bởi các interrupt từ các thiết bị ngoại vi và đây có thể coi là ngẫu nhiên. Hiện nay, entropy còn có thể được sinh ra từ tầng ứng dụng bởi các thuật toán giả ngẫu nhiên hay từ chính bên trong phần cứng - chip Intel và AMD.

Một ví dụ điển hình về mặt bảo mật, chúng ta cần cung cấp 1 bộ số ngẫu nhiên để đảm bảo cho quá trình sinh ra session ID trong quá trình giao tiếp giữa client và server.

Dưới đây là lệnh kiểm tra entropy hiện tại của hệ thống.

[email protected] ~ $ cat /proc/sys/kernel/random/entropy_avail
3520

Đổi góc nhìn một chút, từ góc nhìn của một developer về ứng dụng, chúng ta có một số cách để tăng tốc độ khởi động cho một ứng dụng Java. Cụ thể như với trường hợp của bên mình - có rất nhiều ứng dụng sử dụng Apache Tomcat, mình google nghía qua một chút thì có một số cách tối ưu thời gian khởi động như:

config/server.xml  engine startstopthreads="0"
  host startstopthreads="0"
conf/catalina.propertiesorg.apache.catalina.startup.ContextConfig.jarsToSkip=*.jar
WEB-INF/web.xmlload-on-startup>0</load-on-startup


Nhưng câu chuyện của bên mình lại không chỉ dừng lại ở mặt ứng dụng!

Khi công ty mình chuyển dịch ứng dụng từ VMWare hay từ máy chủ vật lý lên OpenStack VM (Base on KVM Virtualization), bọn mình đã gặp ngay vấn đề đầu tiên đó là ứng dụng Java Tomcat khởi động cực kỳ chậm so với hệ thống trước đó, cho dù bên mình đã cắt chuyển gần như nguyên vẹn 100% môi trường. Vấn đề nhanh chóng được khoanh vùng bằng việc bật hết DEBUG mode trong ứng dụng và bọn mình nhận ra rằng có cái gì đó bất thường trong khoảng thời gian ứng dụng thiết lập phiên ban đầu khi service được khởi tạo.

Ok - Google thấy gì?
Và bọn mình cũng dường như ngay lập tức nhận ra rằng đây là vấn đề chung của mọi nhà ^^



Sự thật đằng sau vấn đề này đó là các ứng dụng bên mình đều sử dụng SecureRandom class của Java và khi ứng dụng khởi động thì các class này không được "feed" đủ lượng entropy cần thiết.

Quay lại với môi trường Cloud, đây không phải là vấn đề riêng của OpenStack mà là đối với ảo hóa nói chung. Nếu ứng dụng chạy trên máy chủ vật lý thì thường lượng entropy đã đủ lớn để cung cấp cho ứng dụng bởi lẽ máy chủ vật lý sẽ có nhiều thiết bị ngoại vi hơn đồng thời số lần khởi động lại hay "xóa đi, tạo lại" cũng ít hơn so với máy ảo. Thật vậy, nhiều nhà cung cấp Public Cloud cũng khuyên nghị người dùng cài gói haveged vào máy ảo để tăng tốc và bảo mật cho máy ảo.

Mình cũng đã thử nghiệm việc cài đặt haveged và kết quả đúng như mong đợi, ứng dụng có thời gian khởi động tương đương thời gian khởi động trước đó ở VMWare hay ở server vật lý.

apt-get install haveged

yum install haveged

Tuy nhiên, quá trình cắt chuyển ứng dụng của bên mình ưu tiên tối đa cho việc giữ nguyên môi trường, vì vậy việc cài thêm 1 gói "lạ" vào các máy chủ là điều không mong muốn.

Câu hỏi đặt ra lúc này: Với khả năng tuy chỉnh của việc triển khai OpenStack, chúng ta có thể làm gì để vừa đạt được mục tiêu cung cấp đủ entropy cho máy ảo mà vẫn không phải tác động vào máy chủ? Dưới đây là câu trả lời của mình bằng việc cấu hình thêm property cho flavor và image của OpenStack!

openstack flavor set FLAVOR-NAME \

    --property hw_rng:allowed=True \

    --property hw_rng:rate_bytes=2000 \

    --property hw_rng:rate_period=2000

openstack image set  --property hw_rng_model=virtio IMAGE_NAME

Posted on