通常、Function Compute ランタイム環境では、ビルトインの依存関係を使用します。関数にサードパーティ製依存関係が必要な場合は、まず関数コードが格納されているフォルダに依存関係をダウンロードします。すべてのコードを依存関係と併せてパッケージ化し、パッケージ全体を Function Compute にアップロードします。本トピックでは、関数用にサードパーティ製依存関係をインストールする方法について説明します。
圧縮されたコードパッケージを Function Compute にアップロードします。アップロードには、コマンドラインツール fcli、Function Compute コンソール、または、Object Storage Service(OSS)を使用できます。コンソールよりコードパッケージをアップロードする場合、「OSS からインポート」を選択し、zip ファイルまたはフォルダをアップロードします。Windows OS の場合は、Function Compute コンソールを使用したコードパッケージのアップロードを推奨します。
パッケージ要件
関数を作成する際は、コードパッケージを指定します。圧縮されたパッケージをアップロードする際は、次の点にご注意ください。
コードのフォルダではなく、フォルダ内のすべてのファイルをパッケージ化します。また、関数ハンドラのファイルがパッケージのルートディレクトリに保存されていることをご確認ください。
Windows OS の場合、関数コードのディレクトリに移動の上、すべてのファイルを選択し、右クリックして ZIP パッケージに圧縮します。
Linux OS の場合、zip コマンドを実行してコードパッケージを生成します。その際、元ファイルとしてコードフォルダ下のファイルをすべて指定します。たとえば、コマンド「zip code.zip /home/code/*」 を実行すると、必要なファイルがパッケージ化されます。その後、パッケージ名を変更します。
サンプルの説明
本サンプルでは、fcli を使用してコードパッケージをアップロードします。ファイルをパッケージ化する際、次の点にご注意ください。
依存関係を関数が保存されているフォルダにダウンロードします。
コードのフォルダではなく、フォルダ内のすべてのファイルをパッケージ化します。
Node.js ランタイム環境でのパッケージ化
mysql 外部ライブラリをパッケージ化
次の例は、fcli を使用して MySQL にアクセスする MySQL モジュールを追加する方法について説明します。
コードおよび依存モジュールを格納するディレクトリを作成します。
mkdir /tmp/code
依存関係を「/tmp/code」ディレクトリにインストールします。
cd /tmp/code
npm install mysql
コードファイルを作成してファイル名を「index.js」とし、「/tmp/code」ディレクトリに保存します。 コードに
mysql
と入力します。var mysql = require('mysql');
exports.handler = function(event, context, callback) {
var connection = mysql.createConnection({
host : 'localhost',
user : 'me',
password : 'secret',
database : 'my_db'
});
connection.connect();
connection.query('SELECT 1 + 1 AS solution', function (error, results, fields) {
if (error) return callback(error);
console.log('The solution is: ', results[0].solution);
callback(null, results[0].solution);
});
connection.end();
};
ファイルを保存すると、
/tmp/code
ディレクトリの情報は次のようになります。ls -l /tmp/code
-rw-r--r-- 1 rockuw wheel 511 Aug 15 17:58 index.js
drwxr-xr-x 13 rockuw wheel 442 Aug 15 18:01 node_modules
fcli を使用して関数を作成し、呼び出します。
fcli shell
# サービスに移動
cd serviceName
# 関数の作成
mkf functionName -h index.handler -t nodejs6 -d /tmp/code
# 関数の実行
invk functionName
実行ファイルを呼び出す
関数で Node.js で開発されていない外部ツールを使用できます。たとえば、C++ または Go コードをコンパイルしたシェルスクリプトまたは実行ファイルを関数で使用するとします。この場合も、その外部ツールとコードを併せてパッケージ化し、関数内で外部コマンドを実行して使用します。
たとえば、シェルスクリプト「script.sh」を実行するには、スクリプトを「/tmp/code」ディレクトリにパッケージ化します。現在のコードが格納されているディレクトリを取得するには、process.env['FC_FUNC_CODE_PATH']
コマンドを実行します。
シェルスクリプトの実行方法は次のとおりです。
var exec = require('child_process');
exports.handler = function (event, context, callback) {
var scriptPath = process.env['FC_FUNC_CODE_PATH'] + '/script.sh';
exec.exec('bash ' + scriptPath, {}, function (err, stdout, stderr) {
if (err) return callback(err);
console.log(stdout, stderr);
callback(null, stdout);
});
};
C、C++ または Go コードをコンパイルした実行ファイルは、Function Compute ランタイム環境と互換である必要があります。Function Compute では、次の Node.js ランタイム環境に対応しています。
- Linux カーネルバージョン:Linux 4.4.24-2.al7.x86_64
- Docker ベースイメージ:Docker Pull Node: 6.10
Python ランタイム環境でパッケージ化
カスタム化モジュールを使用するには、コードと併せてモジュールをパッケージ化します。たとえば、fcli よりモジュール PyMySQL を追加して MySQL にアクセスする手順は次のとおりです。
コードおよび関連モジュールを格納するディレクトリを作成します。
mkdir /tmp/code
「main.py」という名のコードファイルを作成し、「/tmp/code」ディレクトリに保存します。コードに
pymysql
と記述します。import pymysql.cursors
# データベースに接続
connection = pymysql.connect(host='localhost',
user='user',
password='passwd',
db='db',
charset='utf8mb4',
cursorclass=pymysql.cursors.DictCursor)
def my_handler(event, context):
with connection.cursor() as cursor:
# レコードを 1 つ読み取る
sql = "SELECT count(*) FROM `users`"
cursor.execute(sql)
result = cursor.fetchone()
print(result)
return result
依存関係を「/tmp/code」ディレクトリにインストールします。
pip install PyMySQL
コマンドをそのまま使用して PyMySQL ライブラリをインストールすることができないことにご注意ください。本コマンドを使用して依存関係をインストールすると、複数のディレクトリに分配されます。その代わりに、すべての依存関係ファイルを現在のフォルダにダウンロードすることにより、まとめてパッケージ化され、アップロードされるようにします。次の例では、コード内でpip install --install-option="--install-lib=$(pwd)" PyMySQL
およびpip install -t . PyMySQL
パラメータを使用しています。サードパーティ製ライブラリは、サンドボックス環境でのパッケージ化、関数の検証、トラブルシュートを推奨します。開発環境とランタイム環境との互換性に関する問題を回避することができます。特に関数がバイナリファイルに依存する場合、関連する依存関係をサンドボックス環境でコンパイルします。
cd /tmp/code
fcli shell
Welcome to the Function Compute world. Have fun!
>>> sbox -d testPython -t python2.7
Entering the container. Your code is in the /code direcotry.
# you can also use pip install -t . PyMySQL, here
root@8c26467c375d:/code# pip install --install-option="--install-lib=$(pwd)" PyMySQL
root@8c26467c375d:/code# exit
>>> exit
pip install -t . PyMySQL
により、PyMySQL の依存するすべての Python ライブラリは、既にインストールされているか否かにかかわらず、ダウンロードされます。モジュールのバージョンが指定されていない場合は、「インストール - オプション」に記載されている方法でインストールすることを推奨します。この方法だと、ローカルに存在しない Python ライブラリのみがダウンロードされるため、ローカルの外部パッケージのサイズ削減に役立ちます。次の図では、赤枠内のライブラリはダウロードされません。サンドボックス環境を使用する場合には、次の点にご注意ください。
sbox コマンドを実行するには、必ず Docker をインストールしておきます。Docker のインストール方法の詳細については、『Docker のインストール』 をご参照ください。
sbox コマンドの実行に必要なイメージは Docker の公式レポジトリに格納されています。イメージのダウンロードに時間がかかるようであれば、Alibaba Cloud の Container Service のご利用を推奨します。詳細は、「関連ドキュメント」を参照。
Linux OS では、root ユーザーのみ Docker を実行することができます。したがって、
sudo fcli shell
コマンドを実行して fcli を使用できるようにします。あるいは、関連ドキュメント に従ってLinux ホストを設定し、非 root ユーザーが Docker を操作できるようにします。インストールすると、
/tmp/code
ディレクトリは次のようになります。ls /tmp/code
PyMySQL-0.7.11.dist-info main.py pymysql
fcli を使用して関数を作成し、呼び出します。
fcli shell
>>> mkf my-func -h main.my_handler -t python2.7 -d /tmp/code
>>> invk my-func
依存関係が .so ファイルといったダイナミックリンクライブラリを含む場合は、それらのファイルは lib フォルダに格納します。Function Compute ランタイム環境は、path 変数に lib ディレクトリを追加します。
外部コマンドの使用
Python で開発されていない外部ツールを関数で使用する場合があります。たとえば、C++ または Go コードをコンパイルしたシェルスクリプトまたは実行ファイルを関数で使用することができます。この場合も、その外部ツールとコードを併せてパッケージ化し、関数内で外部コマンドを実行して使用します。
たとえば、シェルスクリプト「script.sh」を実行するには、「/tmp/code」ディレクトリにパッケージ化する必要があります。現在のコードが保存されているディレクトリを取得するには、 process.env['FC_FUNC_CODE_PATH']
コマンドを実行します。
次の例は、シェルスクリプトの実行方法を示します。
import os
import subprocess
def my_handler(event, context):
script_path = os.environ.get('FC_FUNC_CODE_PATH') + '/script.sh'
ret = subprocess.check_output(['bash', script_path])
return ret
C、 C++、または Go コードをコンパイルした実行ファイルは、Function Compute ランタイム環境と互換性がある必要があります。Function Compute の対応している Python ランタイム環境は次のとおりです。
- Linux kernel version: Linux 4.4.24-2.al7.x86_64
- Docker base image: Docker Pull Python: 2.7; Docker Pull Python: 3.6
Java ランタイム環境でパッケージ化
Java ランタイム環境では、コードおよび依存関係を JAR ファイルにパッケージ化します。ファイルを Function Compute にアップロードします。依存関係を使用する場合は、pom.xml ファイルに依存関係を追加すればよく、JAR ファイルにパッケージ化します。Maven または IDEA でもパッケージ化することができます。
Maven を使用してパッケージ化
次の例では、pom.xml ファイルに OSS Java SDK を追加しています。
<dependencies>
<dependency>
<groupId>com.aliyun.fc.runtime</groupId>
<artifactId>fc-java-core</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>2.6.1</version>
</dependency>
</dependencies>
「maven-assembly-plugin」プラグインを「pom.xml」ファイルに追加して依存関係を JAR ファイルにパッケージ化します。
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<appendAssemblyId>false</appendAssemblyId> <!-- this means id is not appended to the jar name -->
</configuration>
<executions>
<execution>
<id>make-assembly</id> <!-- this is used for inheritance merges -->
<phase>package</phase> <!-- bind to the packaging phase -->
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
IDEA を使用してパッケージ化
基本操作は次のとおりです。
[Project Structure] -> [Artifacts] -> [Add Jar] -> [From modules with dependencies] -> [Apply] -> [OK].
[Build] -> [Build Artifacts] -> [build]
詳細は、IDEA の公式 Web サイト内の『モジュールを JAR ファイルにパッケージ化』をご参照ください。
参照
- 依存関係を定義することもできます。ただし、その際は関数コードを定義した依存関係と併せてパッケージ化し、Function Compute にパッケージをアップロードします。