빠른 시작
이 빠른 시작 가이드로 NetFUNNEL 4 Android 에이전트를 5-10분 내에 실행하세요.
이 가이드로 할 수 있는 것
- 코드 기반 통합: Android 코드에서 NetFUNNEL 함수를 호출하여 트래픽 제어 적용
- 기본 제어: Activity 진입, 버튼 클릭 및 API 호출에 대한 진입 속도 제한
- 구간 제어: 특정 애플리케이션 구간 내 동시 사용자 제어
제어 유형 선택
어떤 제어 유형을 사용해야 할지 확실하지 않으신가요? 통합 방법 개요를 확인하여 기본 제어와 구간 제어 방식을 비교하고 사용 사례에 가장 적합한 방법을 찾아보세요.
사전 요구사항
- NetFUNNEL 콘솔 액세스
- Android Studio 환경
- Android 개발 기본 이해 (Java/Kotlin)
- Android API Level 22 (Lollipop 5.1) 이상
연습 프로젝트 제공
연습용 기본 프로젝트가 필요하신가요? NetFUNNEL SDK 통합 연습을 위한 Android 애플리케이션 (단일 Activity) 템플릿을 포함한 샘플 프로젝트를 확인해보세요.
1단계: SDK 설치 및 에이전트 초기화
1.1 NetFUNNEL 콘솔에서 SDK 다운로드
- NetFUNNEL 콘솔에 로그인합니다
- 에이전트 → 모바일 에이전트 → Android로 이동합니다
- ZIP 파일을 다운로드합니다:
netfunnel-android-agent-{{version}}.zip - AAR 파일을 얻기 위해 압축 해제합니다:
netfunnel-android-agent-debug-{{version}}.aar(개발용)netfunnel-android-agent-release-{{version}}.aar(프로덕션용)
1.2 의존성 추가
1. AAR 파일 배치:
app/libs/디렉토리 생성- AAR 파일을
app/libs/에 복사
2. app/build.gradle 구성:
- Kotlin DSL (build.gradle.kts)
- Groovy DSL (build.gradle)
dependencies {
// NetFUNNEL Android 에이전트
implementation(files("libs/netfunnel-android-agent-debug-{{version}}.aar"))
// 외부 의존성
val ktorVersion = "2.3.12"
val serializationVersion = "1.6.3"
implementation("io.ktor:ktor-client-core:$ktorVersion")
implementation("io.ktor:ktor-client-okhttp:$ktorVersion")
implementation("io.ktor:ktor-client-content-negotiation:$ktorVersion")
implementation("io.ktor:ktor-serialization-gson:$ktorVersion")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:$serializationVersion")
}
android {
compileSdk = 34
defaultConfig {
minSdk = 22
targetSdk = 34
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = "1.8"
}
}
dependencies {
// NetFUNNEL Android 에이전트
implementation files("libs/netfunnel-android-agent-debug-{{version}}.aar")
// 외부 의존성
implementation "io.ktor:ktor-client-core:2.3.12"
implementation "io.ktor:ktor-client-okhttp:2.3.12"
implementation "io.ktor:ktor-client-content-negotiation:2.3.12"
implementation "io.ktor:ktor-serialization-gson:2.3.12"
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.3"
}
android {
compileSdk 34
defaultConfig {
minSdk 22
targetSdk 34
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
}
3. AndroidManifest.xml에 인터넷 권한 추가:
<uses-permission android:name="android.permission.INTERNET" />
1.3 에이전트 초기화
NetFUNNEL 콘솔에서 초기화 코드 가져오기:
- 에이전트 → 모바일 에이전트 → Android로 이동
- 실제 클라이언트 ID가 포함된 초기화 코드 복사
Application 클래스에 추가:
중요: 먼저 초기화해야 함
Application.onCreate()에서 super.onCreate() 이전에 초기화합니다. 이 단계를 누락하면 = 우회 모드(보호 없음)입니다.
- Kotlin
- Java
class YourAppNameApplication : Application() {
override fun onCreate() {
super.onCreate()
Netfunnel.initialize(
clientId = "{{CLIENT_ID}}"
)
}
}
public class YourAppNameApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
Netfunnel.INSTANCE.initialize(
"{{CLIENT_ID}}"
);
}
}
AndroidManifest.xml에 Application 클래스 등록:
<application android:name=".YourAppNameApplication">
<!-- Your activities -->
</application>
실제 코드 사용
예제 클라이언트 ID를 콘솔의 실제 클라이언트 ID로 교체하세요.
2단계: 제어 유형 선택
옵션 A: 기본 제어 (5분)
최적 용도: Activity 진입, 버튼 클릭, API 호출
- 프로젝트에 SDK 추가 (자세한 내용은 설치 및 초기화 참조)
- NetFUNNEL 콘솔에서 세그먼트 생성:
프로젝트→세그먼트→세그먼트 생성으로 이동- 기본 제어 선택
- 진입 허용 수를
0으로 설정 (테스트용)
- Activity에 이 코드 추가:
- Kotlin
- Java
import com.nf4.Netfunnel
import com.nf4.NetfunnelCallback
import com.nf4.NetfunnelCompleteCallback
// 사용자가 Activity에 진입할 때
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Netfunnel.nfStart("{{PROJECT_KEY}}", "{{SEGMENT_KEY}}", callback, this)
}
private val callback = object : NetfunnelCallback() {
override fun onSuccess(statusCode: Int, message: String) {
// 사용자가 진행할 수 있음 - 원래 로직 실행
setupUI()
}
override fun onError(statusCode: Int, message: String) {
// 시스템 오류 - 서비스 가용성을 위해 원래 로직 진행
setupUI()
}
override fun onNetworkError(statusCode: Int, message: String) {
// 네트워크 오류 - 로그만 기록, 네트워크 복구 모드에 의존
Log.d("NetFUNNEL", "Network error: $message")
}
override fun onBlock(statusCode: Int, message: String) {
// 사용자가 차단됨 - 적절한 메시지 표시
Log.d("NetFUNNEL", "User blocked: $message")
}
override fun onClose(statusCode: Int, message: String) {
// 사용자가 대기실을 닫음 - 적절히 처리
Log.d("NetFUNNEL", "User closed waiting room: $message")
}
override fun onContinue(
statusCode: Int,
message: String,
aheadWait: Int,
behindWait: Int,
waitTime: String,
progressRate: Int
) {
Log.d("NetFUNNEL", "Continue: $message, waitTime: $waitTime")
}
}
// 사용자가 떠날 때 키 반환
override fun onDestroy() {
super.onDestroy()
Netfunnel.nfStop("{{PROJECT_KEY}}", "{{SEGMENT_KEY}}", completeCallback)
}
import com.nf4.Netfunnel;
import com.nf4.NetfunnelCallback;
import com.nf4.NetfunnelCompleteCallback;
import androidx.annotation.NonNull;
// 사용자가 Activity에 진입할 때
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Netfunnel.INSTANCE.nfStart("{{PROJECT_KEY}}", "{{SEGMENT_KEY}}", callback, this);
}
private final NetfunnelCallback callback = new NetfunnelCallback() {
@Override
public void onSuccess(int statusCode, @NonNull String message) {
// 사용자가 진행할 수 있음 - 원래 로직 실행
setupUI();
}
@Override
public void onError(int statusCode, @NonNull String message) {
// 시스템 오류 - 서비스 가용성을 위해 원래 로직 진행
setupUI();
}
@Override
public void onNetworkError(int statusCode, @NonNull String message) {
// 네트워크 오류 - 로그만 기록, 네트워크 복구 모드에 의존
Log.d("NetFUNNEL", "Network error: " + message);
}
@Override
public void onBlock(int statusCode, @NonNull String message) {
// 사용자가 차단됨 - 적절한 메시지 표시
Log.d("NetFUNNEL", "User blocked: " + message);
}
@Override
public void onClose(int statusCode, @NonNull String message) {
// 사용자가 대기실을 닫음 - 적절히 처리
Log.d("NetFUNNEL", "User closed waiting room: " + message);
}
@Override
public void onContinue(int statusCode, @NonNull String message, int aheadWait, int behindWait, @NonNull String waitTime, int progressRate) {
Log.d("NetFUNNEL", "Continue: " + message + ", waitTime: " + waitTime);
}
};
private final NetfunnelCompleteCallback completeCallback = new NetfunnelCompleteCallback() {
@Override
public void onComplete(int statusCode, @NonNull String message) {
// 키 반환 완료
Log.d("NetFUNNEL", "Key returned successfully");
}
};
// 사용자가 떠날 때 키 반환
@Override
protected void onDestroy() {
super.onDestroy();
Netfunnel.INSTANCE.nfStop("{{PROJECT_KEY}}", "{{SEGMENT_KEY}}", completeCallback);
}
결과: 사용자가 Activity에 진입할 때 대기실이 나타납니다.
옵션 B: 구간 제어 (10분)
최적 용도: 다단계 프로세스, 동시 사용자 제한 유지
- 프로젝트에 SDK 추가 (옵션 A와 동일)
- NetFUNNEL 콘솔에서 세그먼트 생성 (구간 제어 선택)
- 체크아웃/결제 흐름에 이 코드 추가:
- Kotlin
- Java
import com.nf4.Netfunnel
import com.nf4.NetfunnelCallback
import com.nf4.NetfunnelCompleteCallback
// 구간 시작 (예: 결제 프로세스)
fun startCheckout() {
Netfunnel.nfStartSection("{{PROJECT_KEY}}", "{{SEGMENT_KEY}}", callback, this)
}
private val callback = object : NetfunnelCallback() {
override fun onSuccess(statusCode: Int, message: String) {
// 사용자가 구간에 진입함
showCheckoutForm()
}
override fun onError(statusCode: Int, message: String) {
// 시스템 오류 - 서비스 가용성을 위해 원래 로직 진행
showCheckoutForm()
}
override fun onNetworkError(statusCode: Int, message: String) {
// 네트워크 오류 - 로그만 기록, 네트워크 복구 모드에 의존
Log.d("NetFUNNEL", "Network error: $message")
}
override fun onBlock(statusCode: Int, message: String) {
// 사용자가 차단됨 - 적절한 메시지 표시
Log.d("NetFUNNEL", "User blocked: $message")
}
override fun onClose(statusCode: Int, message: String) {
// 사용자가 대기실을 닫음 - 적절히 처리
Log.d("NetFUNNEL", "User closed waiting room: $message")
}
override fun onContinue(
statusCode: Int,
message: String,
aheadWait: Int,
behindWait: Int,
waitTime: String,
progressRate: Int
) {
Log.d("NetFUNNEL", "Continue: $message, waitTime: $waitTime")
}
}
// 구간 종료 (예: 결제 완료 후)
fun completeCheckout() {
// 결제 완료 로직
processPayment()
// 성공적인 완료 후 키 반환
Netfunnel.nfStopSection("{{PROJECT_KEY}}", "{{SEGMENT_KEY}}", completeCallback)
}
import com.nf4.Netfunnel;
import com.nf4.NetfunnelCallback;
import com.nf4.NetfunnelCompleteCallback;
import androidx.annotation.NonNull;
// 구간 시작 (예: 결제 프로세스)
public void startCheckout() {
Netfunnel.INSTANCE.nfStartSection("{{PROJECT_KEY}}", "{{SEGMENT_KEY}}", callback, this);
}
private final NetfunnelCallback callback = new NetfunnelCallback() {
@Override
public void onSuccess(int statusCode, @NonNull String message) {
// 사용자가 구간에 진입함
showCheckoutForm();
}
@Override
public void onError(int statusCode, @NonNull String message) {
// 시스템 오류 - 서비스 가용성을 위해 원래 로직 진행
showCheckoutForm();
}
@Override
public void onNetworkError(int statusCode, @NonNull String message) {
// 네트워크 오류 - 로그만 기록, 네트워크 복구 모드에 의존
Log.d("NetFUNNEL", "Network error: " + message);
}
@Override
public void onBlock(int statusCode, @NonNull String message) {
// 사용자가 차단됨 - 적절한 메시지 표시
Log.d("NetFUNNEL", "User blocked: " + message);
}
@Override
public void onClose(int statusCode, @NonNull String message) {
// 사용자가 대기실을 닫음 - 적절히 처리
Log.d("NetFUNNEL", "User closed waiting room: " + message);
}
@Override
public void onContinue(int statusCode, @NonNull String message, int aheadWait, int behindWait, @NonNull String waitTime, int progressRate) {
Log.d("NetFUNNEL", "Continue: " + message + ", waitTime: " + waitTime);
}
};
private final NetfunnelCompleteCallback completeCallback = new NetfunnelCompleteCallback() {
@Override
public void onComplete(int statusCode, @NonNull String message) {
// 키 반환 완료
Log.d("NetFUNNEL", "Section key returned successfully");
}
};
// 구간 종료 (예: 결제 완료 후)
public void completeCheckout() {
// 결제 완료 로직
processPayment();
// 성공적인 완료 후 키 반환
Netfunnel.INSTANCE.nfStopSection("{{PROJECT_KEY}}", "{{SEGMENT_KEY}}", completeCallback);
}
결과: 사용자가 체크아웃 구간에 진입하기 전에 큐에서 대기하여 제어된 동시성을 유지합니다.
3단계: 작동 확인
기본 제어의 경우:
- 세그먼트에서 진입 허용 수를 0으로 설정 (대기실이 나타나야 함)
- 대기실이 올바르게 표시되는지 확인 (예상 대기 시간 표시)
- 진입 허용 수를 1로 설정 (즉시 진입해야 함)
- 로그 또는 네트워크 모니터링에서 키 반환 확인
구간 제어의 경우:
- 세그먼트에서 진입 허용 수를 0으로 설정 (대기실이 나타나야 함)
- 대기실이 올바르게 표시되는지 확인 (예상 대기 시간 표시 안 됨)
- 진입 허용 수를 1로 설정 (즉시 구간에 진입해야 함)
- 구간을 통해 탐색 (Section1 → Section2 → End)
- 로그에서 키 타임아웃 연장 확인 (5003 요청 찾기)
- 구간 완료 시 키 반환 확인
도움이 필요하신가요?
- 문제 해결: 일반적인 문제 및 해결 방법
- NetFUNNEL 메시지에 대한 Android 로그 확인 (
printLog = true활성화) - 프로젝트/세그먼트 키가 콘솔과 정확히 일치하는지 확인