【「動作保証はどこまで?」SIerのためのシステム保守の基本】

SIer Tech Blog
2025年3月25日
【「動作保証はどこまで?」SIerのためのシステム保守の基本】
業務システムの保守は、SIerにとって重要な責務の一つです。本記事では、システム保守の範囲定義から具体的な保守活動まで、実践的なアプローチを解説します。
1. システム保守の基本概念
1.1 保守の種類と範囲
システム保守は以下の4つの種類に分類されます:
- 是正保守:バグ修正や障害対応
- 予防保守:将来的な問題の予防
- 適応保守:環境変化への対応
- 完全化保守:機能改善や拡張
1.2 保守範囲の定義
// 保守範囲を定義するクラスの例
@Data
@Builder
public class MaintenanceScope {
// 保守対象システム
private List<SystemComponent> targetSystems;
// 保守レベル
private MaintenanceLevel level;
// サービス時間
private ServiceHours serviceHours;
// 応答時間
private ResponseTime responseTime;
// 除外事項
private List<ExclusionItem> exclusions;
}
// 保守レベルの定義
public enum MaintenanceLevel {
BASIC(Arrays.asList(
MaintenanceType.CORRECTIVE,
MaintenanceType.PREVENTIVE
)),
STANDARD(Arrays.asList(
MaintenanceType.CORRECTIVE,
MaintenanceType.PREVENTIVE,
MaintenanceType.ADAPTIVE
)),
PREMIUM(Arrays.asList(
MaintenanceType.CORRECTIVE,
MaintenanceType.PREVENTIVE,
MaintenanceType.ADAPTIVE,
MaintenanceType.PERFECTIVE
));
private final List<MaintenanceType> includedTypes;
MaintenanceLevel(List<MaintenanceType> types) {
this.includedTypes = types;
}
}
// サービス時間の定義
@Data
public class ServiceHours {
private DayOfWeek[] workingDays;
private LocalTime startTime;
private LocalTime endTime;
private boolean includesHolidays;
public boolean isWithinServiceHours(LocalDateTime dateTime) {
// 営業時間内かどうかの判定ロジック
if (!Arrays.asList(workingDays).contains(dateTime.getDayOfWeek())) {
return false;
}
LocalTime time = dateTime.toLocalTime();
return !time.isBefore(startTime) && !time.isAfter(endTime);
}
}
2. SLAの設計と管理
2.1 SLA項目の定義
// SLA定義の例
@Data
@Builder
public class ServiceLevelAgreement {
// 可用性要件
private Availability availability;
// 性能要件
private Performance performance;
// 信頼性要件
private Reliability reliability;
// サポート要件
private Support support;
}
// 可用性の定義
@Data
public class Availability {
// 稼働率目標
private BigDecimal targetUptime;
// 計画停止の上限
private Duration maxPlannedDowntime;
// 計画外停止の上限
private Duration maxUnplannedDowntime;
public boolean isWithinSLA(SystemMetrics metrics) {
BigDecimal actualUptime = calculateActualUptime(metrics);
return actualUptime.compareTo(targetUptime) >= 0;
}
}
// 性能要件の定義
@Data
public class Performance {
// レスポンスタイムの目標
private Duration targetResponseTime;
// スループットの目標
private int targetThroughput;
// 同時接続数の上限
private int maxConcurrentUsers;
public boolean isWithinSLA(SystemMetrics metrics) {
return metrics.getAverageResponseTime().compareTo(targetResponseTime) <= 0 &&
metrics.getThroughput() >= targetThroughput;
}
}
2.2 SLA監視の実装
// SLA監視サービスの実装例
@Service
public class SLAMonitoringService {
private final MetricsCollector metricsCollector;
private final AlertService alertService;
private final SLAReportGenerator reportGenerator;
@Scheduled(fixedRate = 300000) // 5分ごとに実行
public void monitorSLA() {
// メトリクスの収集
SystemMetrics metrics = metricsCollector.collectMetrics();
// SLAの評価
evaluateSLA(metrics);
// レポートの生成
generateSLAReport(metrics);
}
private void evaluateSLA(SystemMetrics metrics) {
// 可用性の評価
if (!sla.getAvailability().isWithinSLA(metrics)) {
alertService.sendAlert(
AlertLevel.HIGH,
"Availability SLA violation detected",
createAlertDetails(metrics)
);
}
// 性能の評価
if (!sla.getPerformance().isWithinSLA(metrics)) {
alertService.sendAlert(
AlertLevel.WARNING,
"Performance SLA violation detected",
createAlertDetails(metrics)
);
}
}
private void generateSLAReport(SystemMetrics metrics) {
SLAReport report = reportGenerator.generateReport(metrics);
// レポートの保存と配布
reportRepository.save(report);
notificationService.distributeReport(report);
}
}
// メトリクス収集の実装
@Service
public class MetricsCollector {
private final MeterRegistry registry;
public SystemMetrics collectMetrics() {
return SystemMetrics.builder()
.availability(calculateAvailability())
.responseTime(calculateResponseTime())
.throughput(calculateThroughput())
.errorRate(calculateErrorRate())
.build();
}
private BigDecimal calculateAvailability() {
Timer uptime = registry.timer("system.uptime");
Timer downtime = registry.timer("system.downtime");
return BigDecimal.valueOf(uptime.totalTime(TimeUnit.SECONDS))
.divide(BigDecimal.valueOf(
uptime.totalTime(TimeUnit.SECONDS) +
downtime.totalTime(TimeUnit.SECONDS)
), 4, RoundingMode.HALF_UP);
}
}
3. 保守作業の実践
3.1 定期保守の実装
// 定期保守タスクの実装例
@Service
public class RegularMaintenanceService {
private final SystemHealthChecker healthChecker;
private final DatabaseOptimizer dbOptimizer;
private final LogManager logManager;
@Scheduled(cron = "0 0 1 * * SUN") // 毎週日曜日の午前1時に実行
public void performWeeklyMaintenance() {
try {
// システム状態チェック
healthChecker.checkSystemHealth();
// データベース最適化
dbOptimizer.optimize();
// ログファイルの整理
logManager.cleanup();
// メンテナンス結果の記録
recordMaintenanceResult();
} catch (Exception e) {
handleMaintenanceError(e);
}
}
// データベース最適化の実装
@Service
public class DatabaseOptimizer {
public void optimize() {
// テーブル統計情報の更新
updateTableStatistics();
// インデックスの再構築
rebuildIndexes();
// 不要データの削除
cleanupOldData();
}
private void updateTableStatistics() {
jdbcTemplate.execute("ANALYZE VERBOSE");
}
private void rebuildIndexes() {
List<String> tables = getTargetTables();
for (String table : tables) {
jdbcTemplate.execute("REINDEX TABLE " + table);
}
}
}
}
3.2 障害対応の実装
// 障害対応サービスの実装例
@Service
public class IncidentManagementService {
private final IncidentRepository repository;
private final NotificationService notificationService;
private final RecoveryService recoveryService;
public Incident handleIncident(IncidentReport report) {
// インシデントの登録
Incident incident = createIncident(report);
// 影響度の評価
assessImpact(incident);
// 対応チームへの通知
notifyTeam(incident);
// 復旧作業の開始
startRecovery(incident);
return incident;
}
private void assessImpact(Incident incident) {
ImpactAssessment assessment = ImpactAssessment.builder()
.affectedUsers(calculateAffectedUsers(incident))
.businessImpact(evaluateBusinessImpact(incident))
.systemImpact(evaluateSystemImpact(incident))
.build();
incident.setImpactAssessment(assessment);
incident.setPriority(determinePriority(assessment));
}
private void startRecovery(Incident incident) {
RecoveryPlan plan = recoveryService.createRecoveryPlan(incident);
// 復旧作業の実行
recoveryService.executeRecoveryPlan(plan);
// 進捗の監視
monitorRecoveryProgress(plan);
}
}
// 復旧サービスの実装
@Service
public class RecoveryService {
public RecoveryPlan createRecoveryPlan(Incident incident) {
return RecoveryPlan.builder()
.steps(determineRecoverySteps(incident))
.estimatedTime(calculateEstimatedTime(incident))
.requiredResources(identifyRequiredResources(incident))
.build();
}
public void executeRecoveryPlan(RecoveryPlan plan) {
for (RecoveryStep step : plan.getSteps()) {
try {
executeStep(step);
verifyStepCompletion(step);
} catch (Exception e) {
handleStepFailure(step, e);
if (isStepCritical(step)) {
throw new RecoveryFailedException(
"Critical step failed: " + step.getName(),
e
);
}
}
}
}
}
4. 予防保守の実践
4.1 システム監視の実装
// システム監視サービスの実装例
@Service
public class SystemMonitoringService {
private final MetricsCollector metricsCollector;
private final AlertService alertService;
private final PredictiveAnalyzer predictiveAnalyzer;
@Scheduled(fixedRate = 60000) // 1分ごとに実行
public void monitorSystem() {
// システムメトリクスの収集
SystemMetrics metrics = metricsCollector.collectMetrics();
// 現在の状態の評価
evaluateCurrentState(metrics);
// 将来の問題の予測
predictFutureIssues(metrics);
}
private void evaluateCurrentState(SystemMetrics metrics) {
// リソース使用率の確認
checkResourceUtilization(metrics);
// パフォーマンスの確認
checkPerformance(metrics);
// エラー率の確認
checkErrorRate(metrics);
}
private void predictFutureIssues(SystemMetrics metrics) {
// トレンド分析
List<Trend> trends = predictiveAnalyzer.analyzeTrends(metrics);
// 問題の予測
List<PredictedIssue> predictedIssues =
predictiveAnalyzer.predictIssues(trends);
// 予防的アラートの送信
for (PredictedIssue issue : predictedIssues) {
alertService.sendPreventiveAlert(issue);
}
}
}
// 予測分析の実装
@Service
public class PredictiveAnalyzer {
public List<Trend> analyzeTrends(SystemMetrics metrics) {
List<Trend> trends = new ArrayList<>();
// CPU使用率のトレンド
trends.add(analyzeCpuTrend(metrics));
// メモリ使用率のトレンド
trends.add(analyzeMemoryTrend(metrics));
// ディスク使用率のトレンド
trends.add(analyzeDiskTrend(metrics));
// レスポンスタイムのトレンド
trends.add(analyzeResponseTimeTrend(metrics));
return trends;
}
public List<PredictedIssue> predictIssues(List<Trend> trends) {
List<PredictedIssue> issues = new ArrayList<>();
for (Trend trend : trends) {
if (trend.indicatesPotentialIssue()) {
issues.add(createPredictedIssue(trend));
}
}
return issues;
}
}
4.2 性能チューニング
// 性能チューニングサービスの実装例
@Service
public class PerformanceOptimizationService {
private final DatabaseOptimizer dbOptimizer;
private final CacheOptimizer cacheOptimizer;
private final QueryOptimizer queryOptimizer;
public OptimizationResult optimizePerformance() {
OptimizationResult result = new OptimizationResult();
// データベースの最適化
result.addDatabaseOptimizations(
dbOptimizer.optimize()
);
// キャッシュの最適化
result.addCacheOptimizations(
cacheOptimizer.optimize()
);
// クエリの最適化
result.addQueryOptimizations(
queryOptimizer.optimize()
);
return result;
}
}
// データベース最適化の実装
@Service
public class DatabaseOptimizer {
public List<OptimizationAction> optimize() {
List<OptimizationAction> actions = new ArrayList<>();
// インデックスの分析と最適化
actions.addAll(optimizeIndexes());
// テーブル統計情報の更新
actions.addAll(updateStatistics());
// パーティションの最適化
actions.addAll(optimizePartitions());
return actions;
}
private List<OptimizationAction> optimizeIndexes() {
List<OptimizationAction> actions = new ArrayList<>();
// 未使用インデックスの特定
List<String> unusedIndexes = findUnusedIndexes();
for (String index : unusedIndexes) {
actions.add(new DropIndexAction(index));
}
// 断片化したインデックスの再構築
List<String> fragmentedIndexes = findFragmentedIndexes();
for (String index : fragmentedIndexes) {
actions.add(new RebuildIndexAction(index));
}
return actions;
}
}
5. 保守ドキュメントの管理
5.1 ドキュメント体系の整備
// ドキュメント管理システムの実装例
@Service
public class DocumentationManager {
private final DocumentRepository repository;
private final VersionControl versionControl;
private final DocumentValidator validator;
public Document createDocument(DocumentType type, String content) {
// ドキュメントの作成
Document document = new Document();
document.setType(type);
document.setContent(content);
// バリデーション
validator.validate(document);
// バージョン管理
versionControl.createVersion(document);
// 保存
return repository.save(document);
}
public void updateDocument(Document document) {
// 変更の検証
validator.validateUpdate(document);
// 新しいバージョンの作成
versionControl.createVersion(document);
// 更新の保存
repository.save(document);
}
}
// ドキュメントの種類
public enum DocumentType {
SYSTEM_OVERVIEW(Arrays.asList(
DocumentSection.SYSTEM_ARCHITECTURE,
DocumentSection.COMPONENT_DIAGRAM,
DocumentSection.TECHNOLOGY_STACK
)),
OPERATION_MANUAL(Arrays.asList(
DocumentSection.STARTUP_PROCEDURE,
DocumentSection.SHUTDOWN_PROCEDURE,
DocumentSection.BACKUP_PROCEDURE
)),
MAINTENANCE_GUIDE(Arrays.asList(
DocumentSection.REGULAR_MAINTENANCE,
DocumentSection.TROUBLESHOOTING,
DocumentSection.RECOVERY_PROCEDURE
));
private final List<DocumentSection> requiredSections;
DocumentType(List<DocumentSection> sections) {
this.requiredSections = sections;
}
}
5.2 変更管理の実装
// 変更管理システムの実装例
@Service
public class ChangeManagementService {
private final ChangeRepository repository;
private final ApprovalService approvalService;
private final ImpactAnalyzer impactAnalyzer;
public Change requestChange(ChangeRequest request) {
// 変更の登録
Change change = createChange(request);
// 影響分析
analyzeImpact(change);
// 承認フローの開始
startApprovalFlow(change);
return change;
}
private void analyzeImpact(Change change) {
ImpactAnalysis analysis = impactAnalyzer.analyze(change);
// リスクレベルの判定
RiskLevel riskLevel = determineRiskLevel(analysis);
change.setRiskLevel(riskLevel);
// 必要な承認レベルの設定
ApprovalLevel requiredApproval = determineRequiredApproval(riskLevel);
change.setRequiredApprovalLevel(requiredApproval);
}
private void startApprovalFlow(Change change) {
ApprovalFlow flow = approvalService.createFlow(
change.getRequiredApprovalLevel()
);
// 承認者への通知
notifyApprovers(flow.getApprovers());
// 承認状況の監視開始
monitorApprovalStatus(change, flow);
}
}
6. まとめ
システム保守は、以下の点に注意を払いながら計画的に実施することが重要です:
-
保守範囲の明確化
- 保守対象の明確な定義
- SLAの適切な設定
- 除外事項の明確化
-
予防的アプローチ
- 定期的な監視と分析
- 予防的なメンテナンス
- 性能の最適化
-
効果的な運用管理
- 変更管理の徹底
- ドキュメントの整備
- チーム間の連携
参考文献
- 「実践システム保守」- 技術評論社
- 「ITサービスマネジメント」- 日経BP
- 「システム運用の基本」- 翔泳社
- 「SLA設計の実践」- インプレス
システム保守は、システムの安定運用と継続的な改善を支える重要な活動です。本記事で紹介したアプローチを参考に、効果的な保守体制を構築してください。
関連記事
2025/3/24
【SIerが知るべきログ設計のベストプラクティス】
SIerエンジニアのためのログ設計ガイド。業務システムにおける効果的なログ設計から運用管理まで、実践的なベストプラクティスを解説します。
2025/3/23
【長年運用されている業務システムの"負債"とどう向き合うか?】
SIerエンジニアのための技術的負債管理ガイド。長年運用されてきた業務システムの負債を理解し、効果的に管理・改善していくための実践的なアプローチを解説します。