ara::Runtime::GetInstance 深度解析:Adaptive 平台的运行时核心

引言:运行时环境的重要性

亲爱的朋友,在我们探索了 ara::core::Initialize 这个系统入口之后,让我们继续深入 AUTOSAR Adaptive 平台的另一个核心组件——ara::Runtime::GetInstance。如果说 Initialize 是系统的"创世神",那么 Runtime 就是系统的"中央神经系统",它负责协调和管理整个应用程序的运行生命周期。

想象一下,在一个复杂的自动驾驶系统中,有数十个甚至上百个服务、进程和线程需要协同工作。如何让这些组件知道彼此的存在?如何管理它们的生命周期?如何确保它们能够安全、高效地通信?这就是 ara::Runtime::GetInstance 要解决的核心问题。

第一章:Runtime 概念与设计哲学

1.1 什么是运行时环境?

在 AUTOSAR Adaptive 平台中,运行时环境(Runtime Environment)是一个核心概念。它不是一个具体的进程或服务,而是一个抽象的执行环境,为应用程序提供统一的编程接口和执行上下文。

让我们通过一个对比来理解 Runtime 的角色:

应用程序组件
ara::Runtime
服务发现与管理
生命周期管理
执行管理
状态管理
服务注册
服务查找
服务绑定
进程启动
进程停止
状态监控
功能组管理
执行状态
健康监控
错误恢复

1.2 单例模式的设计考量

GetInstance 方法采用了经典的单例模式,这种设计背后有着深刻的考量:

为什么使用单例模式?

  • 全局唯一性:在整个进程中,Runtime 实例必须是唯一的
  • 资源集中管理:避免重复创建和资源竞争
  • 统一访问点:为所有组件提供一致的运行时接口
  • 生命周期管理:确保与进程生命周期一致
// Runtime 单例的基本结构
namespace ara {
class Runtime {
public:
    // 获取运行时单例实例
    static Runtime& GetInstance();
    
    // 禁用拷贝和移动
    Runtime(const Runtime&) = delete;
    Runtime& operator=(const Runtime&) = delete;
    Runtime(Runtime&&) = delete;
    Runtime& operator=(Runtime&&) = delete;
    
    // 运行时服务接口
    ara::core::Result<ServiceHandle> FindService(const ServiceDescriptor& descriptor);
    ara::core::Result<void> OfferService(const ServiceHandle& handle);
    // ... 其他接口
    
private:
    // 私有构造函数,确保只能通过 GetInstance 获取
    Runtime();
    ~Runtime();
};
} // namespace ara

第二章:GetInstance 的深度技术解析

2.1 线程安全的单例实现

在并发环境中,单例模式的实现需要特别注意线程安全。让我们看看 ara::Runtime::GetInstance 可能的实现方式:

// 现代 C++ 线程安全单例实现
Runtime& Runtime::GetInstance() noexcept {
    // C++11 保证静态局部变量的初始化是线程安全的
    static Runtime instance;
    return instance;
}

这种实现方式的优势:

  • 延迟初始化:只有在第一次调用时才会创建实例
  • 线程安全:C++11 标准保证静态局部变量初始化的线程安全
  • 自动销毁:在程序退出时自动调用析构函数

2.2 初始化时机与依赖关系

Runtime 实例的初始化时机是一个关键设计点。让我们通过序列图来理解其初始化过程:

应用程序Runtime::GetInstanceara::core::Initialize执行管理服务管理状态管理应用程序启动ara::core::Initialize()平台基础初始化返回成功首次访问 RuntimeGetInstance()静态实例初始化构造函数调用初始化执行管理接口初始化服务管理接口初始化状态管理接口建立内部状态机返回 Runtime 引用后续访问GetInstance()直接返回已初始化的实例应用程序Runtime::GetInstanceara::core::Initialize执行管理服务管理状态管理

2.3 错误处理与异常安全

虽然 GetInstance 被声明为 noexcept,但在初始化过程中仍可能遇到错误。让我们分析错误处理策略:

class Runtime {
private:
    Runtime() {
        // 分阶段初始化,确保异常安全
        try {
            // 第一阶段:分配基础资源
            InitializeBasicResources();
            
            // 第二阶段:初始化核心组件
            InitializeCoreComponents();
            
            // 第三阶段:建立服务连接
            EstablishServiceConnections();
            
        } catch (const std::exception& e) {
            // 清理已分配的资源
            CleanupPartialInitialization();
            
            // 记录错误日志
            LogFatal("Runtime initialization failed: {}", e.what());
            
            // 重新抛出或终止,取决于系统策略
            if (IsSafetyCritical()) {
                std::terminate(); // 安全关键系统直接终止
            } else {
                throw;
            }
        }
    }
    
    void InitializeBasicResources() {
        // 分配内存、创建锁等基础操作
        internal_state_ = new InternalState();
        if (!internal_state_) {
            throw std::bad_alloc();
        }
        
        // 初始化线程同步原语
        if (!InitializeSynchronizationPrimitives()) {
            throw RuntimeError::kSynchronizationFailed;
        }
    }
};

第三章:Runtime 的核心服务接口

3.1 服务发现与管理

Runtime 最重要的功能之一就是服务发现和管理。让我们深入了解其服务接口:

class Runtime {
public:
    // 服务发现接口
    ara::core::Result<ServiceHandle> FindService(
        const ServiceDescriptor& descriptor,
        ara::com::ServiceHandleContainer& handles) noexcept;
    
    // 服务提供接口  
    ara::core::Result<void> OfferService(
        const ServiceHandle& handle) noexcept;
    
    // 服务停止接口
    ara::core::Result<void> StopOfferService(
        const ServiceHandle& handle) noexcept;
    
private:
    // 服务发现的具体实现
    class ServiceDiscoveryImpl;
    std::unique_ptr<ServiceDiscoveryImpl> service_discovery_;
};

服务发现的工作流程:

服务消费者
FindService
查询本地缓存
缓存命中?
返回缓存结果
发送服务发现请求
等待服务响应
更新本地缓存
返回发现结果
服务提供者
OfferService
注册服务实例
广播服务可用性
更新服务状态

3.2 执行管理与状态监控

Runtime 还负责与执行管理(Execution Management)交互,监控应用程序状态:

class Runtime {
public:
    // 获取应用程序标识
    ara::core::Result<ApplicationIdentifier> GetApplicationId() const noexcept;
    
    // 报告应用程序状态
    ara::core::Result<void> ReportApplicationState(
        ApplicationState state) noexcept;
    
    // 获取机器状态
    ara::core::Result<MachineState> GetMachineState() const noexcept;
    
    // 注册状态变化回调
    ara::core::Result<CallbackHandle> RegisterStateChangeCallback(
        StateChangeCallback callback) noexcept;
};

第四章:实际应用案例分析

4.1 案例一:感知模块的服务发现与绑定

让我们看一个自动驾驶感知模块如何使用 Runtime 进行服务发现:

class PerceptionServiceClient {
public:
    ara::core::Result<void> Initialize() {
        // 获取 Runtime 实例
        ara::Runtime& runtime = ara::Runtime::GetInstance();
        
        // 构造服务描述符
        ara::com::ServiceDescriptor descriptor;
        descriptor.service_id = "perception_service";
        descriptor.instance_id = "front_camera";
        descriptor.major_version = 1;
        descriptor.minor_version = 0;
        
        // 查找感知服务
        ara::com::ServiceHandleContainer handles;
        auto find_result = runtime.FindService(descriptor, handles);
        
        if (!find_result) {
            LogError("Failed to find perception service: {}", 
                     find_result.Error().Message());
            return find_result.Error();
        }
        
        if (handles.empty()) {
            LogWarning("No perception service instances found");
            return ara::core::Result<void>::FromError(
                ServiceError::kServiceUnavailable);
        }
        
        // 选择第一个可用的服务实例
        selected_handle_ = handles[0];
        
        // 创建服务代理
        auto proxy_result = ara::com::Proxy::Create(selected_handle_);
        if (!proxy_result) {
            LogError("Failed to create service proxy: {}", 
                     proxy_result.Error().Message());
            return ara::core::Result<void>::FromError(proxy_result.Error());
        }
        
        service_proxy_ = std::move(proxy_result.Value());
        
        LogInfo("Perception service connected successfully");
        return ara::core::Result<void>::Ok();
    }
    
    ara::core::Result<PerceptionData> GetPerceptionData() {
        if (!service_proxy_) {
            return ara::core::Result<PerceptionData>::FromError(
                ServiceError::kProxyNotInitialized);
        }
        
        // 通过代理调用服务方法
        return service_proxy_->GetPerceptionData();
    }
    
private:
    ara::com::ServiceHandle selected_handle_;
    std::unique_ptr<ara::com::Proxy> service_proxy_;
};

4.2 案例二:状态管理与健康监控

在安全关键系统中,状态管理和健康监控至关重要:

class HealthMonitoringService {
public:
    ara::core::Result<void> StartMonitoring() {
        // 获取 Runtime 实例
        ara::Runtime& runtime = ara::Runtime::GetInstance();
        
        // 注册状态变化回调
        auto callback_handle = runtime.RegisterStateChangeCallback(
            [this](ApplicationState old_state, ApplicationState new_state) {
                this->OnApplicationStateChanged(old_state, new_state);
            });
            
        if (!callback_handle) {
            LogError("Failed to register state change callback");
            return ara::core::Result<void>::FromError(callback_handle.Error());
        }
        
        callback_handle_ = callback_handle.Value();
        
        // 启动健康监控线程
        monitoring_thread_ = std::thread(&HealthMonitoringService::MonitorHealth, this);
        
        return ara::core::Result<void>::Ok();
    }
    
private:
    void OnApplicationStateChanged(ApplicationState old_state, 
                                   ApplicationState new_state) {
        LogInfo("Application state changed: {} -> {}", 
                ToString(old_state), ToString(new_state));
        
        // 根据状态变化调整监控策略
        switch (new_state) {
            case ApplicationState::kRunning:
                monitoring_level_ = MonitoringLevel::kNormal;
                break;
                
            case ApplicationState::kDegraded:
                monitoring_level_ = MonitoringLevel::kEnhanced;
                break;
                
            case ApplicationState::kEmergency:
                monitoring_level_ = MonitoringLevel::kCritical;
                break;
                
            default:
                monitoring_level_ = MonitoringLevel::kMinimal;
                break;
        }
    }
    
    void MonitorHealth() {
        while (!stop_monitoring_) {
            // 定期检查系统健康状态
            CheckSystemHealth();
            
            // 根据监控级别调整检查频率
            std::chrono::milliseconds interval = GetMonitoringInterval();
            std::this_thread::sleep_for(interval);
        }
    }
    
    std::chrono::milliseconds GetMonitoringInterval() const {
        switch (monitoring_level_) {
            case MonitoringLevel::kNormal:
                return std::chrono::seconds(5);
            case MonitoringLevel::kEnhanced:
                return std::chrono::seconds(2);
            case MonitoringLevel::kCritical:
                return std::chrono::milliseconds(500);
            default:
                return std::chrono::seconds(10);
        }
    }
    
    CallbackHandle callback_handle_;
    std::thread monitoring_thread_;
    std::atomic<bool> stop_monitoring_{false};
    MonitoringLevel monitoring_level_ = MonitoringLevel::kNormal;
};

4.3 案例三:分布式系统中的协同工作

在分布式自动驾驶系统中,多个 ECU 需要通过 Runtime 进行协同:

class DistributedCoordinationManager {
public:
    ara::core::Result<void> InitializeCoordinatedSystem() {
        ara::Runtime& runtime = ara::Runtime::GetInstance();
        
        // 获取当前应用程序在分布式系统中的角色
        auto app_id = runtime.GetApplicationId();
        NodeRole role = DetermineNodeRole(app_id);
        
        // 根据角色初始化不同的服务集合
        switch (role) {
            case NodeRole::kLeader:
                return InitializeLeaderNode();
                
            case NodeRole::kFollower:
                return InitializeFollowerNode();
                
            case NodeRole::kStandalone:
                return InitializeStandaloneNode();
                
            default:
                return ara::core::Result<void>::FromError(
                    CoordinationError::kInvalidRole);
        }
    }
    
private:
    ara::core::Result<void> InitializeLeaderNode() {
        ara::Runtime& runtime = ara::Runtime::GetInstance();
        
        // 领导者节点提供协调服务
        auto coordination_service = CreateCoordinationService();
        auto offer_result = runtime.OfferService(coordination_service);
        
        if (!offer_result) {
            LogError("Failed to offer coordination service");
            return offer_result;
        }
        
        // 启动领导者特定的任务
        StartLeaderElectionMonitor();
        StartFollowerHealthCheck();
        
        LogInfo("Leader node initialized successfully");
        return ara::core::Result<void>::Ok();
    }
    
    ara::core::Result<void> InitializeFollowerNode() {
        ara::Runtime& runtime = ara::Runtime::GetInstance();
        
        // 查找领导者节点的协调服务
        ara::com::ServiceDescriptor leader_descriptor;
        leader_descriptor.service_id = "distributed_coordination";
        leader_descriptor.instance_id = "leader";
        
        ara::com::ServiceHandleContainer handles;
        auto find_result = runtime.FindService(leader_descriptor, handles);
        
        if (!find_result || handles.empty()) {
            LogWarning("No leader found, operating in standalone mode");
            return InitializeStandaloneNode();
        }
        
        // 连接到领导者
        auto connect_result = ConnectToLeader(handles[0]);
        if (!connect_result) {
            LogError("Failed to connect to leader");
            return connect_result;
        }
        
        // 注册到领导者
        auto register_result = RegisterWithLeader();
        if (!register_result) {
            LogError("Failed to register with leader");
            return register_result;
        }
        
        LogInfo("Follower node initialized and registered with leader");
        return ara::core::Result<void>::Ok();
    }
    
    NodeRole DetermineNodeRole(const ApplicationIdentifier& app_id) {
        // 基于应用程序ID、系统配置和当前状态确定节点角色
        // 这可能涉及复杂的决策逻辑
        if (IsDesignatedLeader(app_id)) {
            return NodeRole::kLeader;
        } else if (HasLeaderCapability()) {
            return NodeRole::kLeader; // 具备领导能力
        } else {
            return NodeRole::kFollower;
        }
    }
};

第五章:性能优化与最佳实践

5.1 高效使用 Runtime 单例

虽然 GetInstance 本身是高效的,但不恰当的使用方式可能影响性能:

// 不推荐的做法:频繁调用 GetInstance
class InefficientServiceClient {
public:
    void ProcessRequest() {
        // 每次调用都获取 Runtime 实例(虽然不昂贵,但不必要)
        auto& runtime = ara::Runtime::GetInstance();
        auto result = runtime.FindService(descriptor_, handles_);
        // ...
    }
    
private:
    ServiceDescriptor descriptor_;
    ServiceHandleContainer handles_;
};

// 推荐的做法:缓存 Runtime 引用
class EfficientServiceClient {
public:
    EfficientServiceClient() 
        : runtime_(ara::Runtime::GetInstance()) { // 在构造函数中获取一次
    }
    
    void ProcessRequest() {
        // 直接使用缓存的引用
        auto result = runtime_.FindService(descriptor_, handles_);
        // ...
    }
    
private:
    ara::Runtime& runtime_; // 缓存 Runtime 引用
    ServiceDescriptor descriptor_;
    ServiceHandleContainer handles_;
};

5.2 服务发现优化策略

服务发现可能成为性能瓶颈,特别是在大规模分布式系统中:

class OptimizedServiceDiscovery {
public:
    ara::core::Result<ServiceHandle> FindServiceOptimized(
        const ServiceDescriptor& descriptor) {
        
        // 第一层:线程本地缓存
        auto cached = CheckThreadLocalCache(descriptor);
        if (cached) {
            return cached;
        }
        
        // 第二层:进程内缓存
        cached = CheckProcessCache(descriptor);
        if (cached) {
            UpdateThreadLocalCache(descriptor, cached.Value());
            return cached;
        }
        
        // 第三层:真正的服务发现
        ara::Runtime& runtime = ara::Runtime::GetInstance();
        ara::com::ServiceHandleContainer handles;
        auto result = runtime.FindService(descriptor, handles);
        
        if (!result || handles.empty()) {
            return ara::core::Result<ServiceHandle>::FromError(
                result ? ServiceError::kServiceUnavailable : result.Error());
        }
        
        // 更新缓存
        ServiceHandle selected = handles[0];
        UpdateProcessCache(descriptor, selected);
        UpdateThreadLocalCache(descriptor, selected);
        
        return selected;
    }
    
private:
    // 线程本地缓存
    static thread_local std::unordered_map<ServiceDescriptor, 
                                          ServiceHandle> thread_local_cache_;
    
    // 进程级缓存(需要线程安全)
    std::unordered_map<ServiceDescriptor, ServiceHandle> process_cache_;
    std::mutex cache_mutex_;
    
    ara::core::Result<ServiceHandle> CheckThreadLocalCache(
        const ServiceDescriptor& descriptor) {
        auto it = thread_local_cache_.find(descriptor);
        if (it != thread_local_cache_.end()) {
            // 检查缓存是否过期
            if (!IsCacheExpired(descriptor)) {
                return it->second;
            }
            thread_local_cache_.erase(it);
        }
        return ara::core::Result<ServiceHandle>::FromError(
            CacheError::kCacheMiss);
    }
    
    void UpdateThreadLocalCache(const ServiceDescriptor& descriptor,
                               const ServiceHandle& handle) {
        thread_local_cache_[descriptor] = handle;
    }
};

第六章:错误处理与恢复机制

6.1 Runtime 初始化的错误处理

虽然 GetInstance 通常不会失败,但在极端情况下可能需要处理初始化错误:

class RobustRuntimeAccess {
public:
    ara::core::Result<ara::Runtime*> GetRuntime() {
        try {
            // 尝试获取 Runtime 实例
            return &ara::Runtime::GetInstance();
        } catch (const std::exception& e) {
            LogError("Failed to get Runtime instance: {}", e.what());
            return ara::core::Result<ara::Runtime*>::FromError(
                RuntimeError::kInitializationFailed);
        }
    }
    
    ara::core::Result<void> PerformServiceOperation() {
        auto runtime_result = GetRuntime();
        if (!runtime_result) {
            // Runtime 不可用,尝试恢复
            auto recovery_result = AttemptRuntimeRecovery();
            if (!recovery_result) {
                return recovery_result;
            }
            // 重试获取 Runtime
            runtime_result = GetRuntime();
            if (!runtime_result) {
                return ara::core::Result<void>::FromError(
                    RuntimeError::kUnrecoverable);
            }
        }
        
        // 正常的服务操作
        return runtime_result.Value()->FindService(descriptor_, handles_);
    }
    
private:
    ara::core::Result<void> AttemptRuntimeRecovery() {
        LogWarning("Attempting Runtime recovery");
        
        // 策略1:等待并重试
        for (int i = 0; i < kMaxRecoveryAttempts; ++i) {
            std::this_thread::sleep_for(std::chrono::milliseconds(100));
            try {
                ara::Runtime::GetInstance(); // 测试是否恢复
                LogInfo("Runtime recovery successful");
                return ara::core::Result<void>::Ok();
            } catch (...) {
                // 继续重试
            }
        }
        
        // 策略2:重启相关服务
        return RestartRuntimeServices();
    }
};

第七章:测试策略与模拟

7.1 单元测试中的 Runtime 模拟

在单元测试中,我们通常不希望依赖真实的 Runtime 环境:

// Runtime 接口的模拟实现
class MockRuntime : public ara::Runtime {
public:
    static void SetMockInstance(std::unique_ptr<MockRuntime> mock) {
        mock_instance_ = std::move(mock);
    }
    
    static void ResetMockInstance() {
        mock_instance_.reset();
    }
    
    static Runtime& GetInstance() override {
        if (mock_instance_) {
            return *mock_instance_;
        }
        return RealRuntime::GetInstance();
    }
    
    // 模拟方法
    MOCK_METHOD(ara::core::Result<ServiceHandle>, FindService, 
                (const ServiceDescriptor&, ara::com::ServiceHandleContainer&), 
                (noexcept override));
                
    MOCK_METHOD(ara::core::Result<void>, OfferService, 
                (const ServiceHandle&), (noexcept override));
    
private:
    static std::unique_ptr<MockRuntime> mock_instance_;
};

// 在测试中的使用
class ServiceClientTest : public ::testing::Test {
protected:
    void SetUp() override {
        auto mock_runtime = std::make_unique<MockRuntime>();
        mock_runtime_ = mock_runtime.get();
        MockRuntime::SetMockInstance(std::move(mock_runtime));
    }
    
    void TearDown() override {
        MockRuntime::ResetMockInstance();
        mock_runtime_ = nullptr;
    }
    
    MockRuntime* mock_runtime_;
};

TEST_F(ServiceClientTest, SuccessfulServiceDiscovery) {
    ServiceClient client;
    
    // 设置模拟期望
    ServiceDescriptor expected_descriptor{"test_service", "instance1", 1, 0};
    ServiceHandle expected_handle{/* ... */};
    ara::com::ServiceHandleContainer handles{expected_handle};
    
    EXPECT_CALL(*mock_runtime_, FindService(expected_descriptor, _))
        .WillOnce(::testing::Return(ara::core::Result<ServiceHandle>::Ok()));
    
    // 执行测试
    auto result = client.Initialize();
    EXPECT_TRUE(result);
}

第八章:未来演进与扩展性

8.1 面向云原生的 Runtime 扩展

随着汽车软件向云原生架构演进,Runtime 可能需要扩展以支持新的需求:

class CloudAwareRuntime : public ara::Runtime {
public:
    // 扩展的云感知接口
    ara::core::Result<void> RegisterWithCloud(const CloudEndpoint& endpoint);
    
    ara::core::Result<ServiceHandle> FindCloudService(
        const CloudServiceDescriptor& descriptor);
    
    ara::core::Result<void> SyncWithCloudConfiguration();
    
private:
    // 云连接管理
    std::unique_ptr<CloudConnector> cloud_connector_;
    
    // 本地缓存与云端的同步
    void SynchronizeServiceRegistry();
};

// 工厂方法,支持可插拔的 Runtime 实现
class RuntimeFactory {
public:
    using RuntimeCreator = std::function<std::unique_ptr<Runtime>()>;
    
    static void RegisterRuntime(const std::string& type, RuntimeCreator creator) {
        GetRegistry()[type] = std::move(creator);
    }
    
    static Runtime& GetInstance(const std::string& type = "default") {
        auto& registry = GetRegistry();
        auto it = registry.find(type);
        if (it != registry.end()) {
            // 使用注册的创建器
            static auto instance = it->second();
            return *instance;
        }
        
        // 回退到默认实现
        static ara::Runtime& default_instance = ara::Runtime::GetInstance();
        return default_instance;
    }
    
private:
    static std::unordered_map<std::string, RuntimeCreator>& GetRegistry() {
        static std::unordered_map<std::string, RuntimeCreator> registry;
        return registry;
    }
};

结语:Runtime 的核心价值

亲爱的朋友,通过这次深入的探索,我们看到了 ara::Runtime::GetInstance 在 AUTOSAR Adaptive 平台中的核心地位。它不仅仅是一个简单的单例获取方法,而是整个运行时环境的门户和协调中心。

让我们回顾一下关键要点:

  1. 设计哲学:单例模式确保了全局一致性和资源集中管理
  2. 核心功能:服务发现、生命周期管理、状态监控等关键能力
  3. 实践应用:在感知系统、健康监控、分布式协调等场景中的具体应用
  4. 性能优化:缓存策略、高效使用模式等性能考量
  5. 错误恢复:健壮的错误处理和恢复机制
  6. 测试策略:单元测试中的模拟和验证方法
  7. 未来演进:面向云原生架构的扩展可能性

ara::Runtime::GetInstance 体现了 AUTOSAR Adaptive 平台的设计智慧——在复杂性和简单性之间找到平衡,在功能丰富性和性能效率之间实现优化。

在构建下一代汽车软件系统时,深入理解和正确使用 Runtime 机制,将帮助你构建出更加可靠、可维护和可扩展的解决方案。希望这次深度解析为你提供了宝贵的见解,祝你在汽车软件的创新之旅中取得更大成功!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

青草地溪水旁

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值