Java Eureka案例怎么实操

wen java案例 28

本文目录导读:

Java Eureka案例怎么实操

  1. 项目整体结构
  2. Eureka Server(注册中心)
  3. User-Service(服务提供者)
  4. Order-Service(服务消费者)
  5. 实操步骤和测试
  6. 进阶功能实现
  7. 常见问题解决

我来为你详细介绍Java Eureka的实操案例,从环境搭建到服务注册与发现的完整流程。

项目整体结构

首先创建三个模块:

  • eureka-server:服务注册中心
  • user-service:服务提供者(模拟用户服务)
  • order-service:服务消费者(模拟订单服务)

Eureka Server(注册中心)

1 创建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>2.3.12.RELEASE</version>
    </parent>
    <groupId>com.example</groupId>
    <artifactId>eureka-server</artifactId>
    <version>1.0-SNAPSHOT</version>
    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Hoxton.SR12</spring-cloud.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </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>

2 配置文件 application.yml

server:
  port: 8761
spring:
  application:
    name: eureka-server
eureka:
  instance:
    hostname: localhost
  client:
    register-with-eureka: false
    fetch-registry: false
    service-url:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
  server:
    enable-self-preservation: false  # 关闭自我保护机制
    eviction-interval-timer-in-ms: 5000  # 清理间隔

3 启动类

package com.example.eurekaserver;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServerApplication.class, args);
    }
}

User-Service(服务提供者)

1 创建项目并添加依赖

<?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>2.3.12.RELEASE</version>
    </parent>
    <groupId>com.example</groupId>
    <artifactId>user-service</artifactId>
    <version>1.0-SNAPSHOT</version>
    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Hoxton.SR12</spring-cloud.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </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>

2 配置文件 application.yml

server:
  port: 8081
spring:
  application:
    name: user-service
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
  instance:
    prefer-ip-address: true
    instance-id: ${spring.cloud.client.ip-address}:${server.port}
    lease-renewal-interval-in-seconds: 10
    lease-expiration-duration-in-seconds: 30

3 启动类

package com.example.userservice;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@SpringBootApplication
@EnableEurekaClient
public class UserServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(UserServiceApplication.class, args);
    }
}

4 创建用户服务API

package com.example.userservice.controller;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.Map;
@RestController
@RequestMapping("/api/users")
public class UserController {
    // 模拟用户数据
    private static Map<String, String> users = new HashMap<>();
    static {
        users.put("1", "张三");
        users.put("2", "李四");
        users.put("3", "王五");
    }
    @GetMapping("/{id}")
    public Map<String, Object> getUserById(@PathVariable String id) {
        Map<String, Object> result = new HashMap<>();
        if (users.containsKey(id)) {
            result.put("code", 200);
            result.put("id", id);
            result.put("name", users.get(id));
        } else {
            result.put("code", 404);
            result.put("message", "用户不存在");
        }
        return result;
    }
    @GetMapping("/list")
    public Map<String, Object> listUsers() {
        Map<String, Object> result = new HashMap<>();
        result.put("code", 200);
        result.put("data", users);
        return result;
    }
}

Order-Service(服务消费者)

1 创建项目并添加依赖

<?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>2.3.12.RELEASE</version>
    </parent>
    <groupId>com.example</groupId>
    <artifactId>order-service</artifactId>
    <version>1.0-SNAPSHOT</version>
    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Hoxton.SR12</spring-cloud.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
        </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>

2 配置文件 application.yml

server:
  port: 8082
spring:
  application:
    name: order-service
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
  instance:
    prefer-ip-address: true
# Ribbon配置
user-service:
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RoundRobinRule
    ConnectTimeout: 5000
    ReadTimeout: 5000

3 配置RestTemplate

package com.example.orderservice.config;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@Configuration
public class RestTemplateConfig {
    @Bean
    @LoadBalanced  // 启用负载均衡
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

4 启动类

package com.example.orderservice;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@SpringBootApplication
@EnableEurekaClient
public class OrderServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderServiceApplication.class, args);
    }
}

5 创建订单服务,调用用户服务

package com.example.orderservice.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import java.util.HashMap;
import java.util.Map;
@RestController
@RequestMapping("/api/orders")
public class OrderController {
    @Autowired
    private RestTemplate restTemplate;
    // 使用服务名调用,而不是具体IP和端口
    private static final String USER_SERVICE_URL = "http://user-service/api/users";
    @GetMapping("/create/{userId}/{product}")
    public Map<String, Object> createOrder(@PathVariable String userId, 
                                          @PathVariable String product) {
        Map<String, Object> result = new HashMap<>();
        try {
            // 通过服务名调用用户服务
            String userServiceUrl = USER_SERVICE_URL + "/" + userId;
            Map userInfo = restTemplate.getForObject(userServiceUrl, Map.class);
            if (userInfo != null && (Integer) userInfo.get("code") == 200) {
                result.put("code", 200);
                result.put("message", "订单创建成功");
                result.put("order", new HashMap<String, Object>() {{
                    put("userId", userId);
                    put("product", product);
                    put("userName", userInfo.get("name"));
                }});
            } else {
                result.put("code", 400);
                result.put("message", "用户不存在,订单创建失败");
            }
        } catch (Exception e) {
            result.put("code", 500);
            result.put("message", "订单创建失败:" + e.getMessage());
        }
        return result;
    }
    @GetMapping("/user/{userId}")
    public Map<String, Object> getUserInfo(@PathVariable String userId) {
        // 获取用户信息
        String userServiceUrl = USER_SERVICE_URL + "/" + userId;
        return restTemplate.getForObject(userServiceUrl, Map.class);
    }
    @GetMapping("/users")
    public Map<String, Object> getAllUsers() {
        // 获取所有用户列表
        String userServiceUrl = USER_SERVICE_URL + "/list";
        return restTemplate.getForObject(userServiceUrl, Map.class);
    }
}

实操步骤和测试

1 启动顺序

  1. 先启动 eureka-server
  2. 再启动 user-service
  3. 最后启动 order-service

2 验证注册中心

访问:http://localhost:8761 可以看到注册中心界面,显示已注册的服务实例

3 测试接口

测试用户服务(直接调用):

# 获取用户列表
curl http://localhost:8081/api/users/list
# 获取指定用户
curl http://localhost:8081/api/users/1

测试订单服务(通过Eureka服务发现调用):

# 创建订单(会自动调用用户服务获取用户信息)
curl http://localhost:8082/api/orders/create/1/iPhone13
# 获取用户信息(通过服务发现)
curl http://localhost:8082/api/orders/user/1

进阶功能实现

1 服务高可用配置

创建第二个Eureka Server实例:

application-peer1.yml:

server:
  port: 8761
spring:
  application:
    name: eureka-server
eureka:
  instance:
    hostname: peer1
  client:
    service-url:
      defaultZone: http://peer2:8762/eureka/

application-peer2.yml:

server:
  port: 8762
spring:
  application:
    name: eureka-server
eureka:
  instance:
    hostname: peer2
  client:
    service-url:
      defaultZone: http://peer1:8761/eureka/

2 心跳检测配置

在服务提供者配置中添加:

eureka:
  instance:
    lease-renewal-interval-in-seconds: 5  # 心跳间隔
    lease-expiration-duration-in-seconds: 15  # 过期时间

常见问题解决

1 服务注册失败

# 检查Eureka配置
eureka:
  client:
    register-with-eureka: true  # 确保开启注册
    fetch-registry: true  # 确保开启拉取

2 客户端找不到服务

// 确保RestTemplate添加了@LoadBalanced注解
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
    return new RestTemplate();
}

3 自我保护机制

# 开发环境可以关闭
eureka:
  server:
    enable-self-preservation: false

这个实操案例涵盖了Eureka的核心功能,包括服务注册、服务发现、负载均衡等,建议你按照步骤逐一实现,并通过测试验证功能的正确性。

抱歉,评论功能暂时关闭!