
会社のftpサービスプログラムの負荷テストを任せられました。
このftpサービスはAndroidアプリからのアップロードを対象にしているのですが、
自社には、Android端末が2台しか無いので、
PCからプログラムでどうにか成らないか、試行錯誤をしております。
200kb くらいのデータを200 ユーザーから同時接続・アップロードの
試験をプログラミングで行いたいのです。
当方はJavaの初心者です。
Commons Net のライブラリを使用して
下記のマルチスレッドプログラムを作りました。
/*-------------------------------------------------------------------
import java.io.*;
import org.apache.commons.net.ftp.*;
public class CommNetFtp_Thread extends Thread {
// コンストラクタ 引数の count はローカルの一つのアップロード対象ファイルを
// 番号ファイル名としてリモートへアップロードするための整数値
public CommNetFtp_Thread( int count ) throws Exception{
FileInputStream istream = null;
// 以降は基本的な アップロードのコード (省略のため)
FTPClient ftpclient = new FTPClient();
try {
// サーバに接続
ftpclient.connect( "192.168.0.xxx" );
(省略)
//ログイン
if ( ftpclient.login("username", "password") == false ) {
System.err.println("login fail. Cont: "+ count );
}
// バイナリモードに設定
(省略)
// ファイル送信
istream = new FileInputStream( "D0000111111111111111.wav" );
ftpclient.storeFile( count +".wav", istream );
} catch(Exception e) {
e.printStackTrace();
(例外処理コードも省略させていただきます)
}
}
public void run() {
}
/**
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
CommNetFtp_Thread th1 = new CommNetFtp_Thread( 1 );
CommNetFtp_Thread th2 = new CommNetFtp_Thread( 2 );
// このコードを th200 まで書く(省略)
th1.start();
th2.start();
// このコードを th200 まで書く(省略)
}
}
このようなコードで、同時に複数のコネクションを張り、アップロードが行われたと考えてよろしいのでしょうか?
このプログラムの実行と同時に
リモート側で、"netstat -an" コマンドで、21ポートが複数の ESTABLISH状態を確認できたので、
複数のコネクションが張れてる、と想像しましたが。
どなたか明確な答えをお持ちではないでしょうか?
No.2ベストアンサー
- 回答日時:
> 4 ,5つのftp接続が同時に行われていることを確認しました。
ということですから、同時に4,5スレッドからのリクエストが発生している状況は作れているでしょう。
無限ループでというのは、
public void run() {
System.out.println("Thread-" + count + ": start.");
while(isStop) {
ログイン処理
転送処理
ログアウト処理
}
}
としておけば、常にスレッド数分のリクエストが投げられている状態になるという事です。
ついでに、スレッドを起動する側で
int MAX_THREAD = 200;
TestFtp testFtp[] = new TestFtp[MAX_THREAD];
for (int i=0; i<MAX_THREAD; i++){
TestFtp testFtp[i] = new TestFtp(i);
testFtp[i].start();
Thread.sleep(30000);// 30秒毎にスレッド追加
}
Thread.sleep(10*60*1000);//10分放置
for (int i=0; i<MAX_THREAD; i++){
testFtp[i].isStop = true; // 停止要求
}
for (int i=0; i<MAX_THREAD; i++){
testFtp[i].join(); // 終了待ち
}
とでもしておけば、スレッド数の増加による影響も見れるんじゃないかな?
(ただし、クライアントが十分な性能を持っている場合)
なお、上記コードはコンパイルすらしていないのであしからず。
アドバイスありがとうございます
なるほどです。分かりやすい解説です。
ちなみに、 10コくらいの21ポートEstablish で同時接続を確認しました。
別の質問サイトで回答して頂いた方が仰るには、
『200KBのファイルぐらいなら直ぐに処理が終わるので、
同時に200接続が行われることは無いだろう』とのことでした。
しかし、今回はその完全同時200接続に拘ることはしないつもりです。
まず、スレッド処理の基本から学ぶつもりです。
長い質問にお付き合いいただき、本当に感謝してます。
No.1
- 回答日時:
このコード、コンストラクタで転送してませんか?
スレッドを実行する前の、インスタンス生成時に、
転送終わっちゃってると思うんですが。
仮に、スレッドの実行時に転送するように書き換えても、
そのテストプログラムで保障できるのは、
一定期間内に、200リクエストの処理ができたという事であって、
同時に200リクエストを処理している訳ではありません。
(200リクエスト投げる前に、最初のリクエストが終わってたり、
コネクトについては逐次処理だろうし)
ログインから転送までの処理を無限ループにして、
最大200リクエストの並列処理ができるような
テストプログラムにした方が良いかもしれませんね。
クライアントPCの性能上、同時に200リクエスト投げるのが難しければ、
2台のPCから100スレッドずつとか、10台のPCから20スレッドずつとか
分散するのも手です。
ただし、同時に200転送するようにしたとしても、
ログイン部分は200リクエスト並列にさせるのは
難しいと思います。
200リクエスト分の転送には耐えられるはずなのに、
ログインの負荷には耐えられなくてエラーになる可能性まではテストできません。
蛇足になりますが、FTPの負荷試験程度なら、
JMeterとか使えば、コーディングしなくてもできますよ。
この回答への補足
import java.io.*;
import org.apache.commons.net.ftp.*;
public class TestFtp extends Thread {
int count ; // スレッド処理内で使用する数
// コンストラクタ
public TestFtp( int Cnt ) { // 戻り値にvoid を入れてはダメ
this.count = Cnt;
}
public void run() {
FileInputStream istream = null;
FTPClient ftpclient = new FTPClient();
try {
// サーバに接続
ftpclient.connect( "xxx.xxx.xxx.xx7" );
int reply = ftpclient.getReplyCode();
(省略)
//ログイン
(省略)
}
// バイナリモードに設定
ftpclient.setFileType(FTP.BINARY_FILE_TYPE);
// ファイル送信
istream = new FileInputStream( "D0000000000000000000.wav" );
ftpclient.storeFile( count +".wav", istream );
} catch(Exception e) {
e.printStackTrace();
}
finally {
if ( ftpclient.isConnected() )
try {
ftpclient.disconnect();
} catch (IOException e1) {
e1.printStackTrace();
}
if ( istream != null ) {
try {
istream.close();
}
catch(Exception e) {
e.printStackTrace();
}
}
}
} // run()終了
public static void main(String[] args) {
TestFtp th1 = new TestFtp( 1 );
TestFtp th2 = new TestFtp( 2 );
(このコードを 50まで書く)
th1.start();
th2.start();
(このコードを 50まで書く)
}
}
アップロードが失敗した回数分、
「java.net.SocketException: Connection reset 」がeclipseのコンソールに表れます。
以上
ありがとうございます。
貴交の仰る『ログインから転送までの処理を無限ループにして、』について、
今私は理解できていないのですが。
補足に書いたコードで、再度テストしてみました。
すると、なかなかの確率でアップロードに失敗していました。
一回のプログラム実行で、50のスレッドを生成しアップロードするテストにレベルを下げました。
( ちなみに、アップロード成功率は 83% )
上記のコードで、プログラム実行したと同時に、
サーバ側で > netstat -an をしましたら、
4 ,5つのftp接続が同時に行われていることを確認しました。
( 初期のコードでは、多くても 2つだった )
上記のコードは、同時に接続・リクエストしているプログラムと考えられますでしょうか?
恐縮ですが、ご回答頂けないでしょうか?
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Java java 入力 3 4 3 出力 ABC DEFG HIJ このようなプログラムの書き方を教えてくだ 2 2022/07/15 14:18
- Ruby 【JAVA】数字をひし形に出力するプログラムについて 2 2022/07/11 23:32
- C言語・C++・C# C# DatagridviewにExcelシートを反映するとエラーが出る 2 2023/05/06 17:12
- Java JavaのSingletonパターンのprivateの持つ意味が分かりません。 5 2022/06/12 10:38
- Java javaでのプログラム(配列)について質問です. 2 2022/10/14 22:27
- Java Java プログラム public class Main { public static void 3 2023/08/10 23:46
- Java Java 配列<選挙> 4 2023/07/31 15:07
- Java eclipse実行ができない 2 2022/07/27 04:47
- C言語・C++・C# プログラミング c言語 4 2023/03/07 01:05
- C言語・C++・C# C言語のファイル入力が分かりません 2 2022/05/22 06:35
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
スレッド1とスレッド2を交互に...
-
Odbcオブジェクトの解放の方法
-
Javaプログラムからポップアッ...
-
Javaでのデバッグコード削除
-
PhoneSystemを使うとエラーが出...
-
画面系イベントの優先度を上げたい
-
Threadの停止について
-
tomcat(struts)で起動時に処理...
-
表示待ち時間に「処理中...」の...
-
JavaScriptでページが移動しても
-
javaのプログラムが止まる
-
僕の出身中学校は200人同級生が...
-
「タイプ初期化子が例外をスロ...
-
エクセルVBAで、条件に一致する...
-
今日は こどもの日 で、良い天...
-
配列のメソッド
-
複数の変数を宣言する時、同時...
-
クラス間でのデータ参照
-
変数名の付け方
-
final修飾子を使っているのに、...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
[Java] while(true)の意味
-
tryの終了
-
Javaでのデバッグコード削除
-
Javaアプリケーション実行の返...
-
Javaプログラムからポップアッ...
-
onBlurとonFocusの処理順序につ...
-
Tomcat高負荷時の設定について
-
数値の定数を付ける時
-
アコーディオンメニューをアン...
-
ラジオボタンの選択判定
-
ラベルの表示までが異常に遅い...
-
ExcelVBA で文字列の特定の文字...
-
C#で別スレッドの終了を知りたい
-
素数判定を再帰処理で
-
JavaScriptからJAVAクラスを呼...
-
switch文の中に、throws new Ex...
-
PHPでDB処理中にプログレスバー...
-
C#の処理をリアルタイムに表示...
-
Windowsサービスの処理
-
ftp 同時複数接続の負荷テスト...
おすすめ情報