Java学习第33天 - 微服务架构与云原生

学习目标

深入理解微服务架构设计,掌握云原生技术栈,学习系统设计方法,准备技术面试,了解新技术趋势,完成项目实战。


1. 微服务架构深入

1.1 服务注册与发现

Eureka服务注册中心:

java 复制代码
// Eureka Server配置
@SpringBootApplication
@EnableEurekaServer
@Slf4j
public class EurekaServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServerApplication.class, args);
    }
}

// Eureka Server配置类
@Configuration
public class EurekaServerConfig {
    
    @Bean
    public EurekaInstanceConfigBean eurekaInstanceConfig() {
        EurekaInstanceConfigBean config = new EurekaInstanceConfigBean();
        config.setHostname("localhost");
        config.setInstanceId("eureka-server");
        config.setLeaseRenewalIntervalInSeconds(30);
        config.setLeaseExpirationDurationInSeconds(90);
        return config;
    }
}

// Eureka Client配置
@SpringBootApplication
@EnableEurekaClient
@Slf4j
public class OrderServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderServiceApplication.class, args);
    }
}

// Eureka Client配置类
@Configuration
@Slf4j
public class EurekaClientConfig {
    
    @Value("${eureka.instance.hostname}")
    private String hostname;
    
    @Value("${server.port}")
    private int port;
    
    @Bean
    public EurekaInstanceConfigBean eurekaInstanceConfig() {
        EurekaInstanceConfigBean config = new EurekaInstanceConfigBean();
        config.setHostname(hostname);
        config.setInstanceId(hostname + ":" + port);
        config.setLeaseRenewalIntervalInSeconds(30);
        config.setLeaseExpirationDurationInSeconds(90);
        
        // 健康检查配置
        Map<String, String> metadataMap = new HashMap<>();
        metadataMap.put("management.port", String.valueOf(port));
        config.setMetadataMap(metadataMap);
        
        return config;
    }
}

// 服务发现客户端
@Service
@Slf4j
public class ServiceDiscoveryClient {
    
    @Autowired
    private DiscoveryClient discoveryClient;
    
    @Autowired
    private RestTemplate restTemplate;
    
    // 获取服务实例
    public List<ServiceInstance> getServiceInstances(String serviceName) {
        return discoveryClient.getInstances(serviceName);
    }
    
    // 负载均衡调用服务
    public <T> T callService(String serviceName, String path, Class<T> responseType) {
        List<ServiceInstance> instances = getServiceInstances(serviceName);
        
        if (instances.isEmpty()) {
            throw new RuntimeException("服务不可用: " + serviceName);
        }
        
        // 简单轮询负载均衡
        ServiceInstance instance = instances.get(
            new Random().nextInt(instances.size())
        );
        
        String url = "http://" + instance.getHost() + ":" + instance.getPort() + path;
        return restTemplate.getForObject(url, responseType);
    }
    
    // 使用Ribbon负载均衡
    @LoadBalanced
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
    
    public <T> T callServiceWithRibbon(String serviceName, String path, Class<T> responseType) {
        String url = "http://" + serviceName + path;
        return restTemplate.getForObject(url, responseType);
    }
}

1.2 配置中心

Spring Cloud Config配置中心:

java 复制代码
// Config Server配置
@SpringBootApplication
@EnableConfigServer
@Slf4j
public class ConfigServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(ConfigServerApplication.class, args);
    }
}

// Config Server配置类
@Configuration
public class ConfigServerConfig {
    
    // Git仓库配置
    @Bean
    public GitRepository gitRepository() {
        GitRepository repository = new GitRepository();
        repository.setUri("https://github.com/example/config-repo.git");
        repository.setSearchPaths("config");
        return repository;
    }
}

// Config Client配置
@SpringBootApplication
@EnableConfigClient
@RefreshScope
@Slf4j
public class OrderServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderServiceApplication.class, args);
    }
}

// 动态配置服务
@Service
@Slf4j
public class DynamicConfigService {
    
    @Value("${app.order.timeout:5000}")
    private int orderTimeout;
    
    @Value("${app.order.retry-count:3}")
    private int retryCount;
    
    @Value("${app.feature.enable-new-payment:false}")
    private boolean enableNewPayment;
    
    // 获取配置值
    public int getOrderTimeout() {
        return orderTimeout;
    }
    
    public int getRetryCount() {
        return retryCount;
    }
    
    public boolean isEnableNewPayment() {
        return enableNewPayment;
    }
    
    // 配置变更监听
    @EventListener
    public void handleConfigChange(EnvironmentChangeEvent event) {
        log.info("配置变更: {}", event.getKeys());
        // 处理配置变更逻辑
    }
}

// Nacos配置中心(替代方案)
@Configuration
@Slf4j
public class NacosConfig {
    
    @NacosValue(value = "${app.order.timeout:5000}", autoRefreshed = true)
    private int orderTimeout;
    
    @NacosValue(value = "${app.order.retry-count:3}", autoRefreshed = true)
    private int retryCount;
    
    // 监听配置变更
    @NacosConfigListener(dataId = "order-service", groupId = "DEFAULT_GROUP")
    public void onConfigChange(String newConfig) {
        log.info("配置变更: {}", newConfig);
        // 解析并应用新配置
    }
}

1.3 API网关

Spring Cloud Gateway:

java 复制代码
// Gateway配置
@SpringBootApplication
@Slf4j
public class GatewayApplication {
    public static void main(String[] args) {
        SpringApplication.run(GatewayApplication.class, args);
    }
}

// Gateway路由配置
@Configuration
@Slf4j
public class GatewayConfig {
    
    // 路由配置
    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
        return builder.routes()
            // 订单服务路由
            .route("order-service", r -> r
                .path("/api/orders/**")
                .filters(f -> f
                    .stripPrefix(1)
                    .addRequestHeader("X-Gateway", "Spring-Cloud-Gateway")
                    .retry(config -> config
                        .setRetries(3)
                        .setStatuses(HttpStatus.INTERNAL_SERVER_ERROR)
                        .setMethods(HttpMethod.GET)
                    )
                )
                .uri("lb://order-service")
            )
            // 用户服务路由
            .route("user-service", r -> r
                .path("/api/users/**")
                .filters(f -> f
                    .stripPrefix(1)
                    .circuitBreaker(config -> config
                        .setName("user-service-circuit")
                        .setFallbackUri("forward:/fallback/user")
                    )
                )
                .uri("lb://user-service")
            )
            // 限流路由
            .route("rate-limit-route", r -> r
                .path("/api/public/**")
                .filters(f -> f
                    .requestRateLimiter(config -> config
                        .setRateLimiter(redisRateLimiter())
                        .setKeyResolver(ipKeyResolver())
                    )
                )
                .uri("lb://public-service")
            )
            .build();
    }
    
    // Redis限流器
    @Bean
    public RedisRateLimiter redisRateLimiter() {
        return new RedisRateLimiter(10, 20); // 每秒10个请求,突发20个
    }
    
    // 限流Key解析器(按IP限流)
    @Bean
    public KeyResolver ipKeyResolver() {
        return exchange -> Mono.just(
            exchange.getRequest().getRemoteAddress().getAddress().getHostAddress()
        );
    }
    
    // 全局过滤器
    @Bean
    public GlobalFilter customGlobalFilter() {
        return (exchange, chain) -> {
            ServerHttpRequest request = exchange.getRequest();
            log.info("请求路径: {}", request.getURI().getPath());
            
            // 添加请求头
            ServerHttpRequest modifiedRequest = request.mutate()
                .header("X-Request-Time", String.valueOf(System.currentTimeMillis()))
                .build();
            
            return chain.filter(exchange.mutate().request(modifiedRequest).build());
        };
    }
    
    // 自定义过滤器
    @Component
    @Slf4j
    public static class AuthFilter implements GatewayFilter, Ordered {
        
        @Override
        public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
            ServerHttpRequest request = exchange.getRequest();
            String token = request.getHeaders().getFirst("Authorization");
            
            if (token == null || !isValidToken(token)) {
                ServerHttpResponse response = exchange.getResponse();
                response.setStatusCode(HttpStatus.UNAUTHORIZED);
                return response.setComplete();
            }
            
            return chain.filter(exchange);
        }
        
        private boolean isValidToken(String token) {
            // Token验证逻辑
            return token.startsWith("Bearer ");
        }
        
        @Override
        public int getOrder() {
            return -100;
        }
    }
}

// 降级处理
@RestController
@Slf4j
public class FallbackController {
    
    @RequestMapping("/fallback/user")
    public ResponseEntity<Map<String, Object>> userFallback() {
        Map<String, Object> result = new HashMap<>();
        result.put("code", 500);
        result.put("message", "用户服务暂时不可用,请稍后重试");
        return ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE).body(result);
    }
}

1.4 服务调用

OpenFeign服务调用:

java 复制代码
// Feign客户端接口
@FeignClient(name = "user-service", fallback = UserServiceFallback.class)
public interface UserServiceClient {
    
    @GetMapping("/api/users/{id}")
    UserDTO getUserById(@PathVariable("id") Long id);
    
    @PostMapping("/api/users")
    UserDTO createUser(@RequestBody CreateUserRequest request);
    
    @GetMapping("/api/users")
    List<UserDTO> getUsers(@RequestParam("ids") List<Long> ids);
}

// Feign降级处理
@Component
@Slf4j
public class UserServiceFallback implements UserServiceClient {
    
    @Override
    public UserDTO getUserById(Long id) {
        log.warn("用户服务降级,返回默认用户: {}", id);
        UserDTO user = new UserDTO();
        user.setId(id);
        user.setName("默认用户");
        return user;
    }
    
    @Override
    public UserDTO createUser(CreateUserRequest request) {
        log.warn("用户服务降级,创建用户失败");
        throw new RuntimeException("用户服务不可用");
    }
    
    @Override
    public List<UserDTO> getUsers(List<Long> ids) {
        log.warn("用户服务降级,返回空列表");
        return new ArrayList<>();
    }
}

// Feign配置
@Configuration
@Slf4j
public class FeignConfig {
    
    // 请求拦截器
    @Bean
    public RequestInterceptor requestInterceptor() {
        return requestTemplate -> {
            // 添加请求头
            requestTemplate.header("X-Request-Id", UUID.randomUUID().toString());
            requestTemplate.header("X-Service-Name", "order-service");
        };
    }
    
    // 日志配置
    @Bean
    public Logger.Level feignLoggerLevel() {
        return Logger.Level.FULL;
    }
    
    // 错误解码器
    @Bean
    public ErrorDecoder errorDecoder() {
        return new ErrorDecoder() {
            @Override
            public Exception decode(String methodKey, Response response) {
                if (response.status() == 404) {
                    return new ResourceNotFoundException("资源未找到");
                } else if (response.status() >= 500) {
                    return new ServiceException("服务异常");
                }
                return new RuntimeException("未知错误");
            }
        };
    }
    
    // 重试配置
    @Bean
    public Retryer retryer() {
        return new Retryer.Default(100, 1000, 3);
    }
}

// 使用Feign客户端
@Service
@Slf4j
public class OrderService {
    
    @Autowired
    private UserServiceClient userServiceClient;
    
    public OrderDTO createOrder(CreateOrderRequest request) {
        // 调用用户服务
        UserDTO user = userServiceClient.getUserById(request.getUserId());
        
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        
        // 创建订单逻辑
        OrderDTO order = new OrderDTO();
        order.setUserId(user.getId());
        order.setUserName(user.getName());
        // ...
        
        return order;
    }
}

2. 云原生技术

2.1 Docker容器化

Dockerfile编写:

dockerfile 复制代码
# 多阶段构建
# 第一阶段:构建应用
FROM maven:3.8.4-openjdk-17 AS builder
WORKDIR /app
COPY pom.xml .
RUN mvn dependency:go-offline
COPY src ./src
RUN mvn clean package -DskipTests

# 第二阶段:运行应用
FROM openjdk:17-jre-slim
WORKDIR /app

# 创建非root用户
RUN groupadd -r appuser && useradd -r -g appuser appuser

# 复制构建产物
COPY --from=builder /app/target/*.jar app.jar

# 设置文件权限
RUN chown -R appuser:appuser /app

# 切换到非root用户
USER appuser

# 暴露端口
EXPOSE 8080

# 健康检查
HEALTHCHECK --interval=30s --timeout=3s --start-period=40s --retries=3 \
  CMD curl -f http://localhost:8080/actuator/health || exit 1

# 启动应用
ENTRYPOINT ["java", "-jar", "app.jar"]

Docker Compose配置:

yaml 复制代码
version: '3.8'

services:
  # 订单服务
  order-service:
    build:
      context: ./order-service
      dockerfile: Dockerfile
    container_name: order-service
    ports:
      - "8080:8080"
    environment:
      - SPRING_PROFILES_ACTIVE=docker
      - EUREKA_CLIENT_SERVICE_URL_DEFAULTZONE=http://eureka:8761/eureka/
    depends_on:
      - mysql
      - redis
    networks:
      - microservices-network
    restart: unless-stopped

  # 用户服务
  user-service:
    build:
      context: ./user-service
      dockerfile: Dockerfile
    container_name: user-service
    ports:
      - "8081:8080"
    environment:
      - SPRING_PROFILES_ACTIVE=docker
      - EUREKA_CLIENT_SERVICE_URL_DEFAULTZONE=http://eureka:8761/eureka/
    depends_on:
      - mysql
    networks:
      - microservices-network
    restart: unless-stopped

  # Eureka服务注册中心
  eureka:
    image: springcloud/eureka
    container_name: eureka-server
    ports:
      - "8761:8761"
    networks:
      - microservices-network
    restart: unless-stopped

  # MySQL数据库
  mysql:
    image: mysql:8.0
    container_name: mysql
    environment:
      - MYSQL_ROOT_PASSWORD=root123
      - MYSQL_DATABASE=order_db
    ports:
      - "3306:3306"
    volumes:
      - mysql-data:/var/lib/mysql
    networks:
      - microservices-network
    restart: unless-stopped

  # Redis缓存
  redis:
    image: redis:7-alpine
    container_name: redis
    ports:
      - "6379:6379"
    volumes:
      - redis-data:/data
    networks:
      - microservices-network
    restart: unless-stopped

volumes:
  mysql-data:
  redis-data:

networks:
  microservices-network:
    driver: bridge

Docker操作服务:

java 复制代码
// Docker操作服务
@Service
@Slf4j
public class DockerService {
    
    // 构建Docker镜像
    public void buildImage(String dockerfilePath, String imageName, String tag) {
        try {
            ProcessBuilder processBuilder = new ProcessBuilder(
                "docker", "build",
                "-f", dockerfilePath,
                "-t", imageName + ":" + tag,
                "."
            );
            
            Process process = processBuilder.start();
            int exitCode = process.waitFor();
            
            if (exitCode == 0) {
                log.info("Docker镜像构建成功: {}:{}", imageName, tag);
            } else {
                log.error("Docker镜像构建失败,退出码: {}", exitCode);
            }
        } catch (Exception e) {
            log.error("构建Docker镜像异常", e);
        }
    }
    
    // 运行Docker容器
    public void runContainer(String imageName, String containerName, 
                           Map<String, String> envVars, int port) {
        try {
            List<String> command = new ArrayList<>();
            command.add("docker");
            command.add("run");
            command.add("-d");
            command.add("--name");
            command.add(containerName);
            command.add("-p");
            command.add(port + ":8080");
            
            // 添加环境变量
            for (Map.Entry<String, String> entry : envVars.entrySet()) {
                command.add("-e");
                command.add(entry.getKey() + "=" + entry.getValue());
            }
            
            command.add(imageName);
            
            ProcessBuilder processBuilder = new ProcessBuilder(command);
            Process process = processBuilder.start();
            int exitCode = process.waitFor();
            
            if (exitCode == 0) {
                log.info("Docker容器启动成功: {}", containerName);
            } else {
                log.error("Docker容器启动失败,退出码: {}", exitCode);
            }
        } catch (Exception e) {
            log.error("启动Docker容器异常", e);
        }
    }
}

2.2 Kubernetes部署

Kubernetes部署配置:

yaml 复制代码
# Deployment配置
apiVersion: apps/v1
kind: Deployment
metadata:
  name: order-service
  labels:
    app: order-service
spec:
  replicas: 3
  selector:
    matchLabels:
      app: order-service
  template:
    metadata:
      labels:
        app: order-service
    spec:
      containers:
      - name: order-service
        image: order-service:latest
        ports:
        - containerPort: 8080
        env:
        - name: SPRING_PROFILES_ACTIVE
          value: "k8s"
        - name: EUREKA_CLIENT_SERVICE_URL_DEFAULTZONE
          value: "http://eureka-service:8761/eureka/"
        resources:
          requests:
            memory: "512Mi"
            cpu: "500m"
          limits:
            memory: "1Gi"
            cpu: "1000m"
        livenessProbe:
          httpGet:
            path: /actuator/health/liveness
            port: 8080
          initialDelaySeconds: 60
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /actuator/health/readiness
            port: 8080
          initialDelaySeconds: 30
          periodSeconds: 5

---
# Service配置
apiVersion: v1
kind: Service
metadata:
  name: order-service
spec:
  selector:
    app: order-service
  ports:
  - protocol: TCP
    port: 80
    targetPort: 8080
  type: ClusterIP

---
# Ingress配置
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: order-service-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: api.example.com
    http:
      paths:
      - path: /api/orders
        pathType: Prefix
        backend:
          service:
            name: order-service
            port:
              number: 80

---
# ConfigMap配置
apiVersion: v1
kind: ConfigMap
metadata:
  name: order-service-config
data:
  application.yml: |
    spring:
      datasource:
        url: jdbc:mysql://mysql-service:3306/order_db
      redis:
        host: redis-service
        port: 6379

---
# Secret配置
apiVersion: v1
kind: Secret
metadata:
  name: order-service-secret
type: Opaque
data:
  db-password: cm9vdDEyMw==  # base64编码的密码

Kubernetes操作服务:

java 复制代码
// Kubernetes操作服务
@Service
@Slf4j
public class KubernetesService {
    
    // 创建Deployment
    public void createDeployment(String name, String image, int replicas) {
        try {
            ProcessBuilder processBuilder = new ProcessBuilder(
                "kubectl", "create", "deployment",
                name,
                "--image=" + image,
                "--replicas=" + replicas
            );
            
            Process process = processBuilder.start();
            int exitCode = process.waitFor();
            
            if (exitCode == 0) {
                log.info("Kubernetes Deployment创建成功: {}", name);
            } else {
                log.error("Kubernetes Deployment创建失败,退出码: {}", exitCode);
            }
        } catch (Exception e) {
            log.error("创建Kubernetes Deployment异常", e);
        }
    }
    
    // 扩缩容
    public void scaleDeployment(String name, int replicas) {
        try {
            ProcessBuilder processBuilder = new ProcessBuilder(
                "kubectl", "scale", "deployment",
                name,
                "--replicas=" + replicas
            );
            
            Process process = processBuilder.start();
            int exitCode = process.waitFor();
            
            if (exitCode == 0) {
                log.info("Kubernetes Deployment扩缩容成功: {} -> {}", name, replicas);
            } else {
                log.error("Kubernetes Deployment扩缩容失败,退出码: {}", exitCode);
            }
        } catch (Exception e) {
            log.error("Kubernetes Deployment扩缩容异常", e);
        }
    }
    
    // 滚动更新
    public void rollingUpdate(String name, String newImage) {
        try {
            ProcessBuilder processBuilder = new ProcessBuilder(
                "kubectl", "set", "image",
                "deployment/" + name,
                name + "=" + newImage
            );
            
            Process process = processBuilder.start();
            int exitCode = process.waitFor();
            
            if (exitCode == 0) {
                log.info("Kubernetes滚动更新成功: {} -> {}", name, newImage);
            } else {
                log.error("Kubernetes滚动更新失败,退出码: {}", exitCode);
            }
        } catch (Exception e) {
            log.error("Kubernetes滚动更新异常", e);
        }
    }
}

2.3 Service Mesh

Istio Service Mesh配置:

yaml 复制代码
# VirtualService配置
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: order-service
spec:
  hosts:
  - order-service
  http:
  - match:
    - headers:
        version:
          exact: v2
    route:
    - destination:
        host: order-service
        subset: v2
      weight: 100
  - route:
    - destination:
        host: order-service
        subset: v1
      weight: 90
    - destination:
        host: order-service
        subset: v2
      weight: 10

---
# DestinationRule配置
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: order-service
spec:
  host: order-service
  subsets:
  - name: v1
    labels:
      version: v1
  - name: v2
    labels:
      version: v2
  trafficPolicy:
    loadBalancer:
      simple: ROUND_ROBIN
    connectionPool:
      tcp:
        maxConnections: 100
      http:
        http1MaxPendingRequests: 10
        http2MaxRequests: 100
        maxRequestsPerConnection: 2
    circuitBreaker:
      consecutiveErrors: 5
      interval: 30s
      baseEjectionTime: 30s
      maxEjectionPercent: 50
      minHealthPercent: 50

---
# Gateway配置
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: order-gateway
spec:
  selector:
    istio: ingressgateway
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - api.example.com

3. 系统设计实战

3.1 高并发系统设计

高并发系统架构:

java 复制代码
// 限流服务
@Service
@Slf4j
public class RateLimitService {
    
    // 令牌桶限流
    private final RateLimiter rateLimiter = RateLimiter.create(100.0); // 每秒100个请求
    
    public boolean tryAcquire() {
        return rateLimiter.tryAcquire();
    }
    
    // 滑动窗口限流
    private final Map<String, List<Long>> requestWindows = new ConcurrentHashMap<>();
    private static final int WINDOW_SIZE = 60; // 60秒窗口
    private static final int MAX_REQUESTS = 100; // 最大100个请求
    
    public boolean isAllowed(String key) {
        long currentTime = System.currentTimeMillis() / 1000;
        List<Long> window = requestWindows.computeIfAbsent(key, k -> new ArrayList<>());
        
        // 移除过期请求
        window.removeIf(time -> time < currentTime - WINDOW_SIZE);
        
        if (window.size() >= MAX_REQUESTS) {
            return false;
        }
        
        window.add(currentTime);
        return true;
    }
}

// 缓存服务
@Service
@Slf4j
public class CacheService {
    
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    
    // 多级缓存
    private final Cache<String, Object> localCache = Caffeine.newBuilder()
        .maximumSize(10000)
        .expireAfterWrite(5, TimeUnit.MINUTES)
        .build();
    
    public <T> T get(String key, Class<T> type, Supplier<T> dataLoader) {
        // 一级缓存:本地缓存
        T value = (T) localCache.getIfPresent(key);
        if (value != null) {
            return value;
        }
        
        // 二级缓存:Redis
        value = (T) redisTemplate.opsForValue().get(key);
        if (value != null) {
            localCache.put(key, value);
            return value;
        }
        
        // 三级缓存:数据库
        value = dataLoader.get();
        if (value != null) {
            redisTemplate.opsForValue().set(key, value, 1, TimeUnit.HOURS);
            localCache.put(key, value);
        }
        
        return value;
    }
}

// 异步处理服务
@Service
@Slf4j
public class AsyncProcessService {
    
    @Async("taskExecutor")
    public CompletableFuture<Void> processAsync(String data) {
        // 异步处理逻辑
        log.info("异步处理: {}", data);
        return CompletableFuture.completedFuture(null);
    }
    
    // 线程池配置
    @Bean(name = "taskExecutor")
    public ThreadPoolTaskExecutor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(10);
        executor.setMaxPoolSize(50);
        executor.setQueueCapacity(200);
        executor.setThreadNamePrefix("async-task-");
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        executor.initialize();
        return executor;
    }
}

3.2 分布式系统设计

分布式系统架构:

java 复制代码
// 分布式任务调度
@Service
@Slf4j
public class DistributedTaskScheduler {
    
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    
    // 分布式锁实现任务调度
    public void scheduleTask(String taskId, Runnable task) {
        String lockKey = "task:lock:" + taskId;
        String lockValue = UUID.randomUUID().toString();
        
        try {
            if (tryLock(lockKey, lockValue, 30)) {
                // 检查任务是否已执行
                String executedKey = "task:executed:" + taskId;
                if (redisTemplate.hasKey(executedKey)) {
                    log.info("任务已执行: {}", taskId);
                    return;
                }
                
                // 执行任务
                task.run();
                
                // 标记任务已执行
                redisTemplate.opsForValue().set(executedKey, "1", 1, TimeUnit.HOURS);
            }
        } finally {
            releaseLock(lockKey, lockValue);
        }
    }
    
    private boolean tryLock(String lockKey, String lockValue, long expireTime) {
        Boolean result = redisTemplate.opsForValue()
            .setIfAbsent(lockKey, lockValue, expireTime, TimeUnit.SECONDS);
        return Boolean.TRUE.equals(result);
    }
    
    private void releaseLock(String lockKey, String lockValue) {
        String luaScript = 
            "if redis.call('get', KEYS[1]) == ARGV[1] then " +
            "  return redis.call('del', KEYS[1]) " +
            "else return 0 end";
        
        DefaultRedisScript<Long> script = new DefaultRedisScript<>();
        script.setScriptText(luaScript);
        script.setResultType(Long.class);
        
        redisTemplate.execute(script, Collections.singletonList(lockKey), lockValue);
    }
}

4. 面试准备

4.1 常见面试题

Java基础面试题:

java 复制代码
// 1. 单例模式实现
public class Singleton {
    // 双重检查锁定
    private volatile static Singleton instance;
    
    private Singleton() {}
    
    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
    
    // 静态内部类实现
    private static class SingletonHolder {
        private static final Singleton INSTANCE = new Singleton();
    }
    
    public static Singleton getInstance2() {
        return SingletonHolder.INSTANCE;
    }
}

// 2. 线程安全的单例
public enum SingletonEnum {
    INSTANCE;
    
    public void doSomething() {
        // 业务逻辑
    }
}

// 3. 生产者消费者模式
public class ProducerConsumer {
    private final BlockingQueue<Integer> queue = new LinkedBlockingQueue<>(10);
    
    class Producer implements Runnable {
        @Override
        public void run() {
            try {
                for (int i = 0; i < 100; i++) {
                    queue.put(i);
                    System.out.println("生产: " + i);
                }
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
    }
    
    class Consumer implements Runnable {
        @Override
        public void run() {
            try {
                while (true) {
                    Integer value = queue.take();
                    System.out.println("消费: " + value);
                }
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
    }
}

4.2 算法题

常见算法实现:

java 复制代码
// 快速排序
public class QuickSort {
    public void sort(int[] arr, int low, int high) {
        if (low < high) {
            int pivot = partition(arr, low, high);
            sort(arr, low, pivot - 1);
            sort(arr, pivot + 1, high);
        }
    }
    
    private int partition(int[] arr, int low, int high) {
        int pivot = arr[high];
        int i = low - 1;
        
        for (int j = low; j < high; j++) {
            if (arr[j] < pivot) {
                i++;
                swap(arr, i, j);
            }
        }
        
        swap(arr, i + 1, high);
        return i + 1;
    }
    
    private void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
}

// 二分查找
public class BinarySearch {
    public int search(int[] arr, int target) {
        int left = 0, right = arr.length - 1;
        
        while (left <= right) {
            int mid = left + (right - left) / 2;
            
            if (arr[mid] == target) {
                return mid;
            } else if (arr[mid] < target) {
                left = mid + 1;
            } else {
                right = mid - 1;
            }
        }
        
        return -1;
    }
}

// LRU缓存实现
public class LRUCache {
    private final int capacity;
    private final Map<Integer, Node> cache;
    private final Node head;
    private final Node tail;
    
    public LRUCache(int capacity) {
        this.capacity = capacity;
        this.cache = new HashMap<>();
        this.head = new Node(0, 0);
        this.tail = new Node(0, 0);
        head.next = tail;
        tail.prev = head;
    }
    
    public int get(int key) {
        Node node = cache.get(key);
        if (node == null) {
            return -1;
        }
        moveToHead(node);
        return node.value;
    }
    
    public void put(int key, int value) {
        Node node = cache.get(key);
        if (node == null) {
            Node newNode = new Node(key, value);
            cache.put(key, newNode);
            addToHead(newNode);
            
            if (cache.size() > capacity) {
                Node tail = removeTail();
                cache.remove(tail.key);
            }
        } else {
            node.value = value;
            moveToHead(node);
        }
    }
    
    private void addToHead(Node node) {
        node.prev = head;
        node.next = head.next;
        head.next.prev = node;
        head.next = node;
    }
    
    private void removeNode(Node node) {
        node.prev.next = node.next;
        node.next.prev = node.prev;
    }
    
    private void moveToHead(Node node) {
        removeNode(node);
        addToHead(node);
    }
    
    private Node removeTail() {
        Node lastNode = tail.prev;
        removeNode(lastNode);
        return lastNode;
    }
    
    static class Node {
        int key;
        int value;
        Node prev;
        Node next;
        
        Node(int key, int value) {
            this.key = key;
            this.value = value;
        }
    }
}

5. 新技术趋势

5.1 响应式编程

Reactor响应式编程:

java 复制代码
// 响应式服务
@Service
@Slf4j
public class ReactiveService {
    
    // 创建Flux
    public Flux<String> getDataStream() {
        return Flux.range(1, 10)
            .map(i -> "数据" + i)
            .delayElements(Duration.ofMillis(100))
            .doOnNext(data -> log.info("处理数据: {}", data));
    }
    
    // 创建Mono
    public Mono<String> getSingleData() {
        return Mono.just("单个数据")
            .delayElement(Duration.ofMillis(100))
            .doOnNext(data -> log.info("处理数据: {}", data));
    }
    
    // 组合多个流
    public Flux<String> combineStreams() {
        Flux<String> stream1 = Flux.just("A", "B", "C");
        Flux<String> stream2 = Flux.just("1", "2", "3");
        
        return Flux.zip(stream1, stream2, (s1, s2) -> s1 + s2);
    }
    
    // 错误处理
    public Flux<String> handleError() {
        return Flux.range(1, 10)
            .map(i -> {
                if (i == 5) {
                    throw new RuntimeException("错误");
                }
                return "数据" + i;
            })
            .onErrorResume(error -> {
                log.error("处理错误", error);
                return Flux.just("错误恢复数据");
            });
    }
}

// WebFlux控制器
@RestController
@Slf4j
public class ReactiveController {
    
    @Autowired
    private ReactiveService reactiveService;
    
    @GetMapping("/api/data/stream")
    public Flux<String> getDataStream() {
        return reactiveService.getDataStream();
    }
    
    @GetMapping("/api/data/single")
    public Mono<String> getSingleData() {
        return reactiveService.getSingleData();
    }
}

5.2 虚拟线程(Java 19+)

虚拟线程使用:

java 复制代码
// 虚拟线程服务
@Service
@Slf4j
public class VirtualThreadService {
    
    // 使用虚拟线程
    public void processWithVirtualThread() {
        try (ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor()) {
            for (int i = 0; i < 10000; i++) {
                final int taskId = i;
                executor.submit(() -> {
                    log.info("虚拟线程执行任务: {}", taskId);
                    // 执行任务
                });
            }
        }
    }
    
    // 虚拟线程与CompletableFuture结合
    public CompletableFuture<String> processAsync() {
        return CompletableFuture.supplyAsync(() -> {
            // 业务逻辑
            return "处理结果";
        }, Executors.newVirtualThreadPerTaskExecutor());
    }
}
相关推荐
愤怒的代码13 分钟前
从开发调试到生产上线:全维度 Android 内存监控与分析体系构建
android·java·kotlin
悟能不能悟20 分钟前
java HttpServletRequest 设置header
java·开发语言
悟空码字26 分钟前
SpringBoot整合FFmpeg,打造你的专属视频处理工厂
java·spring boot·后端
独自归家的兔29 分钟前
Spring Boot 版本怎么选?2/3/4 深度对比 + 迁移避坑指南(含 Java 8→21 适配要点)
java·spring boot·后端
郝学胜-神的一滴38 分钟前
线程同步:并行世界的秩序守护者
java·linux·开发语言·c++·程序人生
掉鱼的猫1 小时前
灵动如画 —— 初识 Solon Graph Fluent API 编排
java·openai·workflow
周杰伦fans1 小时前
AndroidStudioJava国内镜像地址gradle
android·java·android-studio
艾莉丝努力练剑1 小时前
【Linux进程控制(一)】进程创建是呼吸,进程终止是死亡,进程等待是重生:进程控制三部曲
android·java·linux·运维·服务器·人工智能·安全
天天摸鱼的java工程师1 小时前
RocketMQ 与 Kafka 对比:消息队列选型的核心考量因素
java·后端