本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
安裝配方
重要
AWS OpsWorks Stacks 服務已於 2024 年 5 月 26 日終止,並已針對新客戶和現有客戶停用。我們強烈建議客戶盡快將其工作負載遷移至其他解決方案。如果您對遷移有任何疑問,請透過 AWS re:Post
安裝配方會指派給 layer 的安裝生命週期事件,並會在執行個體啟動後執行。他們會執行像是安裝套件、建立組態檔案和啟動服務等任務。設定配方完成執行後, AWS OpsWorks Stacks 會執行部署配方,將任何應用程式部署到新的執行個體。
tomcat::setup
tomcat::setup
配方用於指派給 layer 的安裝生命週期事件。
include_recipe 'tomcat::install'
include_recipe 'tomcat::service'
service 'tomcat' do
action :enable
end
# for EBS-backed instances we rely on autofs
bash '(re-)start autofs earlier' do
user 'root'
code <<-EOC
service autofs restart
EOC
notifies :restart, resources(:service => 'tomcat')
end
include_recipe 'tomcat::container_config'
include_recipe 'apache2'
include_recipe 'tomcat::apache_tomcat_bind'
tomcat::setup
配方基本上就是一個中繼配方。它包含一組處理大部分安裝和設定 Tomcat 之詳細資訊和相關套件的依存配方。tomcat::setup
的第一個部分會執行下列配方。下列配方會在稍後進行討論:
-
tomcat::install 配方會安裝 Tomcat 伺服器套件。
-
tomcat::service 配方會設定 Tomcat 服務。
tomcat::setup
的中間部分會啟用並執行 Tomcat 服務:
-
Chef service 資源
會在開機時啟用 Tomcat 服務。 -
Chef bash 資源
會執行 Bash 指令碼來啟動 autofs 協助程式,這是 Amazon EBS 支援執行個體的必要項目。資源接著會通知 service
資源重新啟動 Tomcat 服務。
tomcat::setup
的最後部分會建立組態檔案,安裝及設定前端 Apache 伺服器:
-
tomcat::container_config 配方會建立組態檔案。
-
apache2
配方 (適用於apache2::default
) 是 Stacks AWS OpsWorks 內建配方,可安裝和設定 Apache 伺服器。 -
tomcat::apache_tomcat_bind 配方會設定 Apache 伺服器,做為 Tomcat 伺服器的前端。
注意
您通常可以透過使用內建配方執行一部分的必要任務,省下時間和精力。此配方使用內建的 apache2::default
配方安裝 Apache,而非從零開始實作。如需如何使用內建配方的另一個範例,請參閱部署配方。
下列章節會更詳細的說明 Tomcat 技術指南的安裝配方。如需 apache2
配方的詳細資訊,請參閱 opsworks-cookbooks/apache2
tomcat::install
tomcat::install
配方會安裝 Tomcat 伺服器、OpenJDK 和處理 MySQL 伺服器連線的 Java 連接器程式庫。
tomcat_pkgs = value_for_platform(
['debian', 'ubuntu'] => {
'default' => ["tomcat#{node['tomcat']['base_version']}", 'libtcnative-1', 'libmysql-java']
},
['centos', 'redhat', 'fedora', 'amazon'] => {
'default' => ["tomcat#{node['tomcat']['base_version']}", 'tomcat-native', 'mysql-connector-java']
},
'default' => ["tomcat#{node['tomcat']['base_version']}"]
)
tomcat_pkgs.each do |pkg|
package pkg do
action :install
end
end
link ::File.join(node['tomcat']['lib_dir'], node['tomcat']['mysql_connector_jar']) do
to ::File.join(node['tomcat']['java_dir'], node['tomcat']['mysql_connector_jar'])
action :create
end
# remove the ROOT webapp, if it got installed by default
include_recipe 'tomcat::remove_root_webapp'
配方會執行下列任務:
-
根據執行個體的作業系統建立要安裝的套件清單。
-
安裝清單中的每個套件。
Chef 套件資源
使用適用於 Amazon Linux 和 apt-get
Ubuntu 的適當提供者yum
來處理安裝。套件提供者會將 OpenJDK 做為 Tomcat 的依存安裝,但 MySQL 連接器程式庫必須明確安裝。 -
使用 Chef link 資源
,在 Tomcat 伺服器的 lib 目錄中建立連結到 JDK 中 MySQL 連接器程式庫的 symlink。 使用預設屬性值,Tomcat lib 目錄為
/usr/share/tomcat6/lib
,MySQL 連接器程式庫 (mysql-connector-java.jar
) 則位於/usr/share/java/
。
tomcat::remove_root_webapp
配方會移除 ROOT web 應用程式 (預設為 /var/lib/tomcat6/webapps/ROOT
),避免某些安全問題。
ruby_block 'remove the ROOT webapp' do
block do
::FileUtils.rm_rf(::File.join(node['tomcat']['webapps_base_dir'], 'ROOT'), :secure => true)
end
only_if { ::File.exists?(::File.join(node['tomcat']['webapps_base_dir'], 'ROOT')) && !::File.symlink?(::File.join(node['tomcat']['webapps_base_dir'], 'ROOT')) }
end
only_if
陳述式會確保只有在檔案存在時,配方才會移除他們。
注意
tomcat::service
tomcat::service
配方會建立 Tomcat 服務定義。
service 'tomcat' do
service_name "tomcat#{node['tomcat']['base_version']}"
case node[:platform]
when 'centos', 'redhat', 'fedora', 'amazon'
supports :restart => true, :reload => true, :status => true
when 'debian', 'ubuntu'
supports :restart => true, :reload => false, :status => true
end
action :nothing
end
配方會使用 Chef service 資源supports
屬性,以定義 Chef 管理服務重新啟動、重新載入和在不同作業系統上狀態命令的方式。
-
true
表示 Chef 可使用 init 指令碼或其他服務提供者執行命令。 -
false
表示 Chef 必須嘗試使用其他方式執行命令。
請注意,action
已設為 :nothing
。對於每個生命週期事件, AWS OpsWorks Stacks 會啟動 Chef 執行notifies
資源中包含 template
命令。通知為重新啟動服務的一種便利方式,因為他們只會在組態變更時才會執行此作業。此外,當 Chef 執行具有多個服務的重新啟動通知時,Chef 最多只會重新啟動服務一次。這種做法可避免在嘗試重新啟動未完全運作的服務時可能發生的問題。此為 Tomcat 錯誤的常見來源。
必須為任何使用重新啟動通知的 Chef run 定義 Tomcat 服務。因此,tomcat::service
會包含在數個配方中,確保為每一個 Chef run 定義服務。即使 Chef 執行包含多個 tomcat::service
的執行個體,也不會有任何損失,因為 Chef 會確保每個配方只會在每次執行時執行一次,無論其包含多少次在內。
tomcat::container_config
tomcat::container_config
配方會從技術指南範本檔案建立組態檔案。
include_recipe 'tomcat::service'
template 'tomcat environment configuration' do
path ::File.join(node['tomcat']['system_env_dir'], "tomcat#{node['tomcat']['base_version']}")
source 'tomcat_env_config.erb'
owner 'root'
group 'root'
mode 0644
backup false
notifies :restart, resources(:service => 'tomcat')
end
template 'tomcat server configuration' do
path ::File.join(node['tomcat']['catalina_base_dir'], 'server.xml')
source 'server.xml.erb'
owner 'root'
group 'root'
mode 0644
backup false
notifies :restart, resources(:service => 'tomcat')
end
配方首先會呼叫 tomcat::service
,其將於必要時定義服務。大量的配方皆由兩個 template 資源
Tomcat 環境資訊檔案
第一個 template
資源會使用 tomcat_env_config.erb
範本檔案建立 Tomcat 環境資訊檔案,用於設定像是 JAVA_HOME
等環境變數。預設檔案名稱為 template
資源的引數。tomcat::container_config
會使用 path
屬性覆寫預設值及命名組態檔 /etc/sysconfig/tomcat6
(Amazon Linux) 或 /etc/default/tomcat6
(Ubuntu)。template
資源也會指定檔案的擁有者、群組和模式設定,並指示 Chef 不要建立備份檔案。
若您查看來源碼,通常會有三種版本的 tomcat_env_config.erb
,每一種都位於 templates
目錄中的不同子目錄內。ubuntu
和 amazon
目錄包含其各自作業系統的範本。default
資料夾則包含僅有一行註解的 dummy 範本,僅會在您嘗試在使用不支援作業系統的執行個體上執行此配方時使用。tomcat::container_config
配方不需要指定要使用何種 tomcat_env_config.erb
。Chef 會自動根據檔案精確性
此範例的 tomcat_env_config.erb
檔案大部分由註解組成。若要設定其他環境變數,只需要取消註解適當的行,並提供您喜好的值即可。
注意
任何可能變更的組態設定都應定義為屬性,而非在範本中硬式編碼。如此一來,您便不需要重新撰寫範本以變更設定;您可以直接覆寫屬性。
Amazon Linux 範本只會設定一個環境變數,如下列摘要所示。
...
# Use JAVA_OPTS to set java.library.path for libtcnative.so
#JAVA_OPTS="-Djava.library.path=/usr/lib"
JAVA_OPTS="${JAVA_OPTS} <%= node['tomcat']['java_opts'] %>"
# What user should run tomcat
#TOMCAT_USER="tomcat"
...
JAVA_OPTS 可用來指定 Java 選項 (例如程式庫路徑)。若使用預設屬性值,範本便不會為 Amazon Linux 設定任何 Java 選項。您可以藉由覆寫 ['tomcat']['java_opts']
屬性 (例如:使用自訂 JSON 屬性),來設定您自己的 Java 選項。如需範例,請參閱「建立堆疊」。
Ubuntu 範本會設定數個環境變數,如下列範本摘要所示。
# Run Tomcat as this user ID. Not setting this or leaving it blank will use the
# default of tomcat<%= node['tomcat']['base_version'] %>.
TOMCAT<%= node['tomcat']['base_version'] %>_USER=tomcat<%= node['tomcat']['base_version'] %>
...
# Run Tomcat as this group ID. Not setting this or leaving it blank will use
# the default of tomcat<%= node['tomcat']['base_version'] %>.
TOMCAT<%= node['tomcat']['base_version'] %>_GROUP=tomcat<%= node['tomcat']['base_version'] %>
...
JAVA_OPTS="<%= node['tomcat']['java_opts'] %>"
<% if node['tomcat']['base_version'].to_i < 7 -%>
# Unset LC_ALL to prevent user environment executing the init script from
# influencing servlet behavior. See Debian bug #645221
unset LC_ALL
<% end -%>
若使用預設屬性值,範本便會設定 Ubuntu 環境變數,如下所示:
-
代表 Tomcat 使用者和群組的
TOMCAT6_USER
和TOMCAT6_GROUP
都已設為tomcat6
。若您將 ['tomcat']['base_version'] 設為
tomcat7
,變數名稱會解析為TOMCAT7_USER
和TOMCAT7_GROUP
,並且都會設為tomcat7
。 -
JAVA_OPTS
已設定為-Djava.awt.headless=true -Xmx128m -XX:+UseConcMarkSweepGC
:-
將
-Djava.awt.headless
設為true
會向圖形引擎通知執行個體沒有標題並且也沒有主控台,表示特定圖形應用程式的錯誤行為。 -
-Xmx128m
可確保 JVM 具有足夠的記憶體資源,此範例為 128MB。 -
-XX:+UseConcMarkSweepGC
指定同時標記整理記憶體回收,協助限制記憶體回收造成的暫停。如需詳細資訊,請參閱 Concurrent Mark Sweep Collector Enhancements
。
-
-
若 Tomcat 的版本低於 7,範本會取消設定處理 Ubuntu 錯誤的
LC_ALL
。
注意
若使用預設屬性,部分環境變數便會設為其預設值。但是,明確將環境變數設為屬性表示您可以定義自訂 JSON 屬性覆寫預設屬性,並提供自訂的值。如需覆寫屬性的詳細資訊,請參閱覆寫屬性。
如需完整的範本檔案,請參閱來源碼
Server.xml 組態檔案
第二個 template
資源會使用 server.xml.erb
建立 system.xml
組態檔server.xml.erb
沒有包含任何作業系統限定設定,因此它會位於 template
目錄的 default
子目錄中。
範本使用者使用標準設定,但它也可以為 Tomcat 6 或 Tomcat 7 建立 system.xml
檔案。例如,下列來自範本的伺服器區段的程式碼會為指定的版本適當設定接聽程式。
<% if node['tomcat']['base_version'].to_i > 6 -%>
<!-- Security listener. Documentation at /docs/config/listeners.html
<Listener className="org.apache.catalina.security.SecurityListener" />
-->
<% end -%>
<!--APR library loader. Documentation at /docs/apr.html -->
<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
<!--Initialize Jasper prior to webapps are loaded. Documentation at /docs/jasper-howto.html -->
<Listener className="org.apache.catalina.core.JasperListener" />
<!-- Prevent memory leaks due to use of particular java/javax APIs-->
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
<% if node['tomcat']['base_version'].to_i < 7 -%>
<!-- JMX Support for the Tomcat server. Documentation at /docs/non-existent.html -->
<Listener className="org.apache.catalina.mbeans.ServerLifecycleListener" />
<% end -%>
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
<% if node['tomcat']['base_version'].to_i > 6 -%>
<Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
<% end -%>
範本使用屬性,而非硬式編碼設定,讓您可以藉由定義自訂 JSON 屬性,輕易變更設定。例如:
<Connector port="<%= node['tomcat']['port'] %>" protocol="HTTP/1.1"
connectionTimeout="20000"
URIEncoding="<%= node['tomcat']['uri_encoding'] %>"
redirectPort="<%= node['tomcat']['secure_port'] %>" />
如需詳細資訊,請參閱來源碼
tomcat::apache_tomcat_bind
tomcat::apache_tomcat_bind
配方會啟用 Apache 伺服器做為 Tomcat 的前端,接受傳入的請求,並將他們轉遞至 Tomcat 並將回應傳回用戶端。此範例使用 mod_proxy
execute 'enable mod_proxy for apache-tomcat binding' do
command '/usr/sbin/a2enmod proxy'
not_if do
::File.symlink?(::File.join(node['apache']['dir'], 'mods-enabled', 'proxy.load')) || node['tomcat']['apache_tomcat_bind_mod'] !~ /\Aproxy/
end
end
execute 'enable module for apache-tomcat binding' do
command "/usr/sbin/a2enmod #{node['tomcat']['apache_tomcat_bind_mod']}"
not_if {::File.symlink?(::File.join(node['apache']['dir'], 'mods-enabled', "#{node['tomcat']['apache_tomcat_bind_mod']}.load"))}
end
include_recipe 'apache2::service'
template 'tomcat thru apache binding' do
path ::File.join(node['apache']['dir'], 'conf.d', node['tomcat']['apache_tomcat_bind_config'])
source 'apache_tomcat_bind.conf.erb'
owner 'root'
group 'root'
mode 0644
backup false
notifies :restart, resources(:service => 'apache2')
end
若要啟用 mod_proxy
,您必須啟用 proxy
模組及通訊協定式模組。您有兩個通訊協定模組選項:
-
HTTP:
proxy_http
-
Apache JServ 通訊協定
(ASP): proxy_ajp
AJP 是一種內部 Tomcat 通訊協定。
兩種配方的 execute 資源a2enmod
命令,透過建立必要的 symlink 啟用指定的模組:
-
第一個
execute
資源會啟用proxy
模組。 -
第二個
execute
資源會啟用通訊協定模組,根據預設設為proxy_http
。若您要使用 AJP,您可以定義自訂 JSON 覆寫
apache_tomcat_bind_mod
屬性,將其設為proxy_ajp
。
apache2::service
配方是定義 Apache AWS OpsWorks 服務的 Stacks 內建配方。如需詳細資訊,請參閱 Stacks GitHub AWS OpsWorks 儲存庫中的配方
template
資源使用 apache_tomcat_bind.conf.erb
建立根據預設名為 tomcat_bind.conf
的組態檔案。它會將檔案置放在 ['apache']['dir']/.conf.d
目錄中。['apache']['dir']
屬性會在內建的 apache2
屬性檔案中定義,並根據預設設為 /etc/httpd
(Amazon Linux) 或 /etc/apache2
(Ubuntu)。若 template
資源建立或變更組態檔案,notifies
命令會排程 Apache 服務重新啟動。
<% if node['tomcat']['apache_tomcat_bind_mod'] == 'proxy_ajp' -%>
ProxyPass <%= node['tomcat']['apache_tomcat_bind_path'] %> ajp://localhost:<%= node['tomcat']['ajp_port'] %>/
ProxyPassReverse <%= node['tomcat']['apache_tomcat_bind_path'] %> ajp://localhost:<%= node['tomcat']['ajp_port'] %>/
<% else %>
ProxyPass <%= node['tomcat']['apache_tomcat_bind_path'] %> http://localhost:<%= node['tomcat']['port'] %>/
ProxyPassReverse <%= node['tomcat']['apache_tomcat_bind_path'] %> http://localhost:<%= node['tomcat']['port'] %>/
<% end -%>
範本使用 ProxyPasshttp://localhost:8080
。