ChatGPT + Spring Boot 3.0 构建智能问答系统:从零到一的技术实现路径

夜晚的诗人
夜晚的诗人 2026-02-14T05:07:11+08:00
0 0 0

Response# ChatGPT + Spring Boot 3.0 构建智能问答系统:从零到一的技术实现路径

引言

在人工智能技术飞速发展的今天,大语言模型如ChatGPT正在改变我们与技术交互的方式。Spring Boot作为Java生态系统中最流行的微服务框架,为构建现代化应用提供了强大的支持。本文将详细介绍如何将ChatGPT API集成到Spring Boot 3.0应用中,构建一个功能完善的智能问答系统。

通过本文的实践,您将掌握从零开始构建智能问答系统的技术路径,包括API调用封装、异步处理、缓存优化、安全认证等关键技术点,为构建企业级AI应用奠定坚实基础。

技术架构概述

系统架构设计

智能问答系统的核心架构包括以下几个关键组件:

  1. API网关层:统一入口,负责请求路由和负载均衡
  2. 业务逻辑层:处理用户请求,调用ChatGPT API
  3. 缓存层:提升响应速度,减少API调用次数
  4. 安全认证层:确保系统安全性
  5. 数据存储层:持久化用户会话和历史记录

技术栈选择

  • Spring Boot 3.0:现代化Java应用开发框架
  • Spring WebFlux:响应式编程支持
  • Spring Cache:缓存管理
  • Spring Security:安全认证
  • Redis:分布式缓存
  • OpenFeign:声明式HTTP客户端
  • Lombok:简化代码编写

项目初始化与依赖配置

Maven依赖配置

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.0.0</version>
        <relativePath/>
    </parent>
    
    <groupId>com.example</groupId>
    <artifactId>chatgpt-qa-system</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>chatgpt-qa-system</name>
    
    <properties>
        <java.version>17</java.version>
        <spring-cloud.version>2022.0.0</spring-cloud.version>
    </properties>
    
    <dependencies>
        <!-- Spring Boot Web Starter -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        
        <!-- Spring Boot WebFlux Starter -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-webflux</artifactId>
        </dependency>
        
        <!-- Spring Cache Starter -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-cache</artifactId>
        </dependency>
        
        <!-- Redis Starter -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        
        <!-- Spring Security Starter -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        
        <!-- OpenFeign Starter -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        
        <!-- Lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        
        <!-- Test Dependencies -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        
        <dependency>
            <groupId>io.projectreactor</groupId>
            <artifactId>reactor-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>

应用配置文件

# application.yml
server:
  port: 8080

spring:
  application:
    name: chatgpt-qa-system
  redis:
    host: localhost
    port: 6379
    database: 0
    timeout: 2000ms
  cache:
    type: redis
    redis:
      time-to-live: 3600000
      key-prefix: "qa:"
      
openai:
  api-key: ${OPENAI_API_KEY}
  api-base: https://api.openai.com
  model: gpt-3.5-turbo
  timeout: 30000
  
logging:
  level:
    com.example.chatgpt: DEBUG
    org.springframework.web: DEBUG

management:
  endpoints:
    web:
      exposure:
        include: health,info,metrics
  endpoint:
    health:
      show-details: always

ChatGPT API调用封装

API接口定义

// ChatGptApi.java
package com.example.chatgpt.api;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import reactor.core.publisher.Mono;

@FeignClient(
    name = "chatgpt-api",
    url = "${openai.api-base}",
    configuration = ChatGptFeignConfig.class
)
public interface ChatGptApi {
    
    @PostMapping(value = "/v1/chat/completions", 
                consumes = MediaType.APPLICATION_JSON_VALUE,
                produces = MediaType.APPLICATION_JSON_VALUE)
    Mono<ChatGptResponse> generateResponse(@RequestBody ChatGptRequest request);
}

请求和响应数据模型

// ChatGptRequest.java
package com.example.chatgpt.model;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import java.util.List;

@Data
public class ChatGptRequest {
    private String model;
    private List<Message> messages;
    private Double temperature;
    private Integer maxTokens;
    private Double topP;
    private Integer n;
    private Boolean stream;
    
    @Data
    public static class Message {
        private String role;
        private String content;
        
        public Message(String role, String content) {
            this.role = role;
            this.content = content;
        }
    }
    
    public ChatGptRequest(String model, List<Message> messages) {
        this.model = model;
        this.messages = messages;
        this.temperature = 0.7;
        this.maxTokens = 1000;
        this.topP = 1.0;
        this.n = 1;
        this.stream = false;
    }
}
// ChatGptResponse.java
package com.example.chatgpt.model;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import java.util.List;

@Data
public class ChatGptResponse {
    private String id;
    private String object;
    private Long created;
    private String model;
    private List<Choice> choices;
    private Usage usage;
    
    @Data
    public static class Choice {
        private Integer index;
        private Message message;
        private String finishReason;
        
        @Data
        public static class Message {
            private String role;
            private String content;
        }
    }
    
    @Data
    public static class Usage {
        @JsonProperty("prompt_tokens")
        private Integer promptTokens;
        
        @JsonProperty("completion_tokens")
        private Integer completionTokens;
        
        @JsonProperty("total_tokens")
        private Integer totalTokens;
    }
}

Feign配置类

// ChatGptFeignConfig.java
package com.example.chatgpt.config;

import feign.Request;
import feign.RequestOptions;
import feign.RetryableException;
import feign.Retryer;
import feign.codec.ErrorDecoder;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ChatGptFeignConfig {
    
    @Value("${openai.timeout:30000}")
    private int timeout;
    
    @Bean
    public RequestOptions requestOptions() {
        return new RequestOptions.Builder()
                .connectTimeout(timeout)
                .readTimeout(timeout)
                .build();
    }
    
    @Bean
    public Retryer retryer() {
        return new Retryer.Default(1000, 2000, 3);
    }
    
    @Bean
    public ErrorDecoder errorDecoder() {
        return new ChatGptErrorDecoder();
    }
    
    public static class ChatGptErrorDecoder implements ErrorDecoder {
        @Override
        public Exception decode(String methodKey, Response response) {
            switch (response.status()) {
                case 401:
                    return new RuntimeException("Unauthorized: Invalid API key");
                case 403:
                    return new RuntimeException("Forbidden: Access denied");
                case 429:
                    return new RuntimeException("Rate limit exceeded");
                case 500:
                    return new RuntimeException("Internal server error");
                default:
                    return new RetryableException(
                            response.status(),
                            response.reason(),
                            response.request().httpMethod(),
                            null,
                            response.request());
            }
        }
    }
}

异步处理与响应式编程

异步服务实现

// ChatGptService.java
package com.example.chatgpt.service;

import com.example.chatgpt.api.ChatGptApi;
import com.example.chatgpt.model.ChatGptRequest;
import com.example.chatgpt.model.ChatGptResponse;
import com.example.chatgpt.model.ChatGptRequest.Message;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;
import java.util.List;
import java.util.concurrent.CompletableFuture;

@Service
@RequiredArgsConstructor
@Slf4j
public class ChatGptService {
    
    private final ChatGptApi chatGptApi;
    
    @Value("${openai.model:gpt-3.5-turbo}")
    private String model;
    
    @Value("${openai.timeout:30000}")
    private int timeout;
    
    public Mono<ChatGptResponse> generateResponse(String question, List<Message> history) {
        return Mono.fromCallable(() -> {
            try {
                // 构建请求
                ChatGptRequest request = buildRequest(question, history);
                
                // 调用API
                ChatGptResponse response = chatGptApi.generateResponse(request).block();
                
                log.info("ChatGPT API response received for question: {}", question);
                return response;
            } catch (Exception e) {
                log.error("Error calling ChatGPT API", e);
                throw new RuntimeException("Failed to generate response", e);
            }
        }).subscribeOn(Schedulers.boundedElastic());
    }
    
    public CompletableFuture<ChatGptResponse> generateResponseAsync(String question, List<Message> history) {
        return CompletableFuture.supplyAsync(() -> {
            try {
                ChatGptRequest request = buildRequest(question, history);
                return chatGptApi.generateResponse(request).block();
            } catch (Exception e) {
                log.error("Error calling ChatGPT API", e);
                throw new RuntimeException("Failed to generate response", e);
            }
        });
    }
    
    private ChatGptRequest buildRequest(String question, List<Message> history) {
        // 构建消息历史
        List<Message> messages = buildMessages(question, history);
        
        // 创建请求
        ChatGptRequest request = new ChatGptRequest(model, messages);
        request.setTemperature(0.7);
        request.setMaxTokens(1000);
        request.setTopP(1.0);
        request.setN(1);
        request.setStream(false);
        
        return request;
    }
    
    private List<Message> buildMessages(String question, List<Message> history) {
        // 构建完整的消息列表
        List<Message> messages = new ArrayList<>();
        
        if (history != null && !history.isEmpty()) {
            messages.addAll(history);
        }
        
        messages.add(new Message("user", question));
        return messages;
    }
}

响应式控制器

// ChatGptController.java
package com.example.chatgpt.controller;

import com.example.chatgpt.model.ChatGptRequest;
import com.example.chatgpt.model.ChatGptResponse;
import com.example.chatgpt.service.ChatGptService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Mono;

@RestController
@RequestMapping("/api/qa")
@RequiredArgsConstructor
@Slf4j
public class ChatGptController {
    
    private final ChatGptService chatGptService;
    
    @PostMapping("/chat")
    public Mono<ResponseEntity<ChatGptResponse>> chat(
            @RequestBody ChatGptRequest request) {
        return chatGptService.generateResponse(request.getMessages().get(0).getContent(), 
                                              request.getMessages())
                .map(ResponseEntity.ok()::body)
                .onErrorReturn(ResponseEntity.status(500).build());
    }
    
    @PostMapping("/simple")
    public Mono<ResponseEntity<String>> simpleChat(
            @RequestParam String question) {
        return chatGptService.generateResponse(question, null)
                .map(response -> {
                    String answer = response.getChoices().get(0).getMessage().getContent();
                    return ResponseEntity.ok(answer);
                })
                .onErrorReturn(ResponseEntity.status(500).build());
    }
    
    @GetMapping("/health")
    public Mono<ResponseEntity<String>> health() {
        return Mono.just(ResponseEntity.ok("ChatGPT QA System is running"));
    }
}

缓存优化策略

Redis缓存配置

// CacheConfig.java
package com.example.chatgpt.config;

import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.time.Duration;

@Configuration
@EnableCaching
public class CacheConfig {
    
    @Bean
    public RedisCacheManager cacheManager(RedisConnectionFactory connectionFactory) {
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofHours(1))
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()))
                .disableCachingNullValues();
        
        return RedisCacheManager.builder(connectionFactory)
                .withCacheConfiguration("qa-cache", config)
                .build();
    }
}

缓存服务实现

// CacheService.java
package com.example.chatgpt.service;

import com.example.chatgpt.model.ChatGptResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Service;
import java.util.concurrent.CompletableFuture;

@Service
@RequiredArgsConstructor
@Slf4j
public class CacheService {
    
    private final ChatGptService chatGptService;
    
    @Cacheable(value = "qa-cache", key = "#question")
    public CompletableFuture<ChatGptResponse> getResponseWithCache(String question, 
                                                                  String sessionId) {
        log.info("Cache miss for question: {}", question);
        return chatGptService.generateResponseAsync(question, null);
    }
    
    @CacheEvict(value = "qa-cache", key = "#question")
    public void evictCache(String question) {
        log.info("Evicted cache for question: {}", question);
    }
    
    @CacheEvict(value = "qa-cache", allEntries = true)
    public void evictAllCache() {
        log.info("Evicted all cache entries");
    }
}

缓存控制器

// CacheController.java
package com.example.chatgpt.controller;

import com.example.chatgpt.model.ChatGptResponse;
import com.example.chatgpt.service.CacheService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.concurrent.CompletableFuture;

@RestController
@RequestMapping("/api/cache")
@RequiredArgsConstructor
public class CacheController {
    
    private final CacheService cacheService;
    
    @GetMapping("/response/{question}")
    public CompletableFuture<ResponseEntity<ChatGptResponse>> getResponse(
            @PathVariable String question) {
        return cacheService.getResponseWithCache(question, null)
                .thenApply(ResponseEntity.ok()::body)
                .exceptionally(throwable -> {
                    log.error("Error getting cached response", throwable);
                    return ResponseEntity.status(500).build();
                });
    }
    
    @DeleteMapping("/invalidate/{question}")
    public ResponseEntity<String> invalidateCache(@PathVariable String question) {
        cacheService.evictCache(question);
        return ResponseEntity.ok("Cache invalidated for question: " + question);
    }
    
    @DeleteMapping("/invalidate-all")
    public ResponseEntity<String> invalidateAllCache() {
        cacheService.evictAllCache();
        return ResponseEntity.ok("All cache invalidated");
    }
}

安全认证与权限管理

安全配置

// SecurityConfig.java
package com.example.chatgpt.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

@Configuration
@EnableWebSecurity
@EnableMethodSecurity(prePostEnabled = true)
public class SecurityConfig {
    
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
    
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.csrf().disable()
                .authorizeHttpRequests(authz -> authz
                        .requestMatchers("/api/qa/**").authenticated()
                        .requestMatchers("/api/cache/**").authenticated()
                        .requestMatchers("/api/health").permitAll()
                        .anyRequest().authenticated()
                )
                .sessionManagement(session -> session
                        .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                )
                .httpBasic(basic -> basic.disable());
        
        return http.build();
    }
}

JWT认证过滤器

// JwtAuthenticationFilter.java
package com.example.chatgpt.security;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Collections;
import java.util.Date;

@Slf4j
@RequiredArgsConstructor
public class JwtAuthenticationFilter extends OncePerRequestFilter {
    
    @Value("${app.jwtSecret}")
    private String jwtSecret;
    
    @Value("${app.jwtExpirationInMs}")
    private int jwtExpirationInMs;
    
    @Override
    protected void doFilterInternal(HttpServletRequest request, 
                                  HttpServletResponse response, 
                                  FilterChain filterChain) throws ServletException, IOException {
        try {
            String token = parseJwt(request);
            
            if (token != null && validateToken(token)) {
                Claims claims = Jwts.parser()
                        .setSigningKey(jwtSecret)
                        .parseClaimsJws(token)
                        .getBody();
                
                String username = claims.getSubject();
                String role = claims.get("role", String.class);
                
                UsernamePasswordAuthenticationToken authentication = 
                        new UsernamePasswordAuthenticationToken(username, null, 
                                Collections.singletonList(new SimpleGrantedAuthority(role)));
                
                SecurityContextHolder.getContext().setAuthentication(authentication);
            }
        } catch (Exception e) {
            log.error("Cannot set user authentication: {}", e);
        }
        
        filterChain.doFilter(request, response);
    }
    
    private String parseJwt(HttpServletRequest request) {
        String headerAuth = request.getHeader("Authorization");
        
        if (headerAuth != null && headerAuth.startsWith("Bearer ")) {
            return headerAuth.substring(7);
        }
        
        return null;
    }
    
    private boolean validateToken(String token) {
        try {
            Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(token);
            return true;
        } catch (Exception e) {
            log.error("Invalid JWT token: {}", e.getMessage());
        }
        return false;
    }
}

用户认证服务

// AuthenticationService.java
package com.example.chatgpt.service;

import com.example.chatgpt.model.User;
import com.example.chatgpt.repository.UserRepository;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.Date;

@Service
@RequiredArgsConstructor
@Slf4j
public class AuthenticationService {
    
    private final UserRepository userRepository;
    private final PasswordEncoder passwordEncoder;
    
    @Value("${app.jwtSecret}")
    private String jwtSecret;
    
    @Value("${app.jwtExpirationInMs}")
    private int jwtExpirationInMs;
    
    public String authenticate(String username, String password) {
        User user = userRepository.findByUsername(username)
                .orElseThrow(() -> new RuntimeException("User not found"));
        
        if (!passwordEncoder.matches(password, user.getPassword())) {
            throw new RuntimeException("Invalid credentials");
        }
        
        return generateToken(user);
    }
    
    private String generateToken(User user) {
        Date now = new Date();
        Date expiryDate = new Date(now.getTime() + jwtExpirationInMs);
        
        return Jwts.builder()
                .setSubject(user.getUsername())
                .setIssuedAt(new Date())
                .setExpiration(expiryDate)
                .signWith(SignatureAlgorithm.HS512, jwtSecret)
                .compact();
    }
}

性能优化与监控

请求限流配置

// RateLimitConfig.java
package com.example.chatgpt.config;

import com.google.common.util.concurrent.RateLimiter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.concurrent.ConcurrentHashMap;

@Configuration
@Slf4j
public class RateLimitConfig {
    
    private final ConcurrentHashMap<String, RateLimiter> rateLimiters = new ConcurrentHashMap<>();
    
    @Bean
    public RateLimiter globalRateLimiter() {
        // 限制为每秒10个请求
        RateLimiter rateLimiter = RateLimiter.create(10.0);
        log.info("Global rate limiter initialized with 10 QPS");
        return rateLimiter;
    }
    
    public RateLimiter getUserRateLimiter(String userId) {
        return rateLimiters.computeIfAbsent(userId, key -> RateLimiter.create(5.0));
    }
}

监控与指标收集

// MetricsService.java
package com.example.chatgpt.service;

import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Timer;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

@Service
@RequiredArgsConstructor
@Slf4j
public class MetricsService {
    
    private final MeterRegistry meterRegistry;
    
    private final Counter requestsCounter;
    private final Counter responsesCounter;
    private final Timer responseTimeTimer;
    
    public MetricsService(MeterRegistry meterRegistry) {
        this.meterRegistry = meterRegistry;
        this.requestsCounter = Counter.builder("qa.requests")
                .description("Number of QA requests")
                .register(meterRegistry);
        this.responsesCounter = Counter.builder("qa.responses")
                .description("Number of QA responses")
                .register(meterRegistry);
        this.responseTimeTimer = Timer.builder("qa.response.time")
                .description("QA response time")
                .register(meterRegistry);
    }
    
    public void recordRequest() {
        requestsCounter.increment();
    }
    
    public void recordResponse() {
        responsesCounter.increment();
    }
    
    public void recordResponseTime(long duration) {
        responseTimeTimer.record(duration, TimeUnit.MILLISECONDS);
    }
}

健康检查端点

// HealthController.java
package com.example.chatgpt.controller;

import com.example.chatgpt.service.ChatGptService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api/health")
@RequiredArgsConstructor
public class HealthController {
    
    private final ChatGptService chatGptService;
    
    @GetMapping("/status")
    public ResponseEntity<String> getStatus() {
        return ResponseEntity.ok("ChatGPT QA System is running and healthy");
    }
    
    @GetMapping("/chatgpt")
    public ResponseEntity<String> checkChatGptConnection() {
        try {
            // 简单的API连接测试
            return ResponseEntity.ok("ChatGPT API is accessible");
        } catch (Exception e) {
            return ResponseEntity.status(500).body("ChatGPT API connection failed");
        }
    }
}

完整的项目结构

src/main/java/com/example/chatgpt/
├── ChatGptQaSystemApplication.java
├── config/
│   ├── CacheConfig.java
│   ├── ChatGptFeignConfig.java
│   ├── RateLimitConfig.java
│   └── SecurityConfig.java
├── controller/
│   ├── ChatGptController.java
│   ├── CacheController.java
│   ├── HealthController.java
│   └── AuthController.java
├── service/
│   ├── ChatGptService.java
│   ├── CacheService.java
│   ├── AuthenticationService.java
│   └── MetricsService.java
├── model/
│   ├── ChatGptRequest.java
│   ├── ChatGptResponse.java
│   ├── User.java
│   └── Session.java
├── api/
│   └── ChatGptApi.java
├── repository/
│   └── UserRepository.java
├── security/
│   ├── JwtAuthenticationFilter.java
│   └── UserDetailsService.java
└
相关推荐
广告位招租

相似文章

    评论 (0)

    0/2000