Spring Cloud 之 服务注册与发现实战

一. 启动Eureka Server集群

准备二台云主机,二个eureka server服务互相进行复制。准备二个application.yml配置,分别如下:

application-server1.yml

spring:
 application:
name: eurekaServer1
server: port: 8761 eureka: instance: hostname: eurekaServer1 appname: eurekaServer1 client: registerWithEureka: true fetchRegistry: true serviceUrl: defaultZone: http://eurekaServer2:${server.port}/eureka/

application-server2.yml

spring:
 application:
  name: eurekaServer2
server: port: 8761 eureka: instance: hostname: eurekaServer2 appname: eurekaServer2 client: registerWithEureka: true fetchRegistry: true serviceUrl: defaultZone: http://eurekaServer1:${server.port}/eureka/

 启动时利用springboot 的 profile机制分别进行启动:java -jar  eureka-server.jar --spring.profiles.active={profile名}  方式让不同的 application-{profile名}.yml文件生效

二. 启动服务Provider (此处以发送手机验证码的服务为例)

简单提供一个Controller

@RestController
@RequestMapping(value = "/ecshop/api/1.0")
public class SmsController {
    @Autowired
    private SmsUtil smsUtil;

    @RequestMapping(value = "sendMobileCode", method = RequestMethod.GET)
    public Result sendMobileCode(String mobile, String bizType) {
        smsUtil.sentMobileCode(mobile, bizType);
        Result result = new Result(true, "0", "手机验证码发送成功", false);
        return result;
    }

}

 需要pom中添加

<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>

配置文件 application.yml

spring: 
  application: 
    name: commonservices      //此处必须要配置,否则会导致ribbon找不到服务
  http:
    encoding: 
      force: true
      charset: UTF-8
      enabled: true
server:
  tomcat: 
    uri-encoding: UTF-8
  port: 1001 
eureka:
  instance:
    appname: commonservices
  client:
    serviceUrl:
      defaultZone: http://eurekaServer1:8761/eureka/,http://eurekaServer2:8761/eureka/

启动类

@SpringBootApplication
@EnableDiscoveryClient
public class CommonsApplication 
{
    public static void main( String[] args )
    {
        SpringApplication.run(CommonsApplication.class, args) ;
    }
}

三. 设置服务调用接口

@FeignClient("commonservices")    //注解中应填写相应服务的spring.application.name对应的值
public interface SmsApi {

    @RequestMapping(value = "/ecshop/api/1.0/sendMobileCode", method = RequestMethod.GET)   //访问路径要和真实服务的路径一致
    public Result sendMobileCode(@RequestParam("mobile") String mobile, @RequestParam("bizType") String bizType) ; //参数前一定要有@RequestParam注解
    
}

注:1. 返回类型 Result 一定要有无参的构造函数,否则 Feign 会 无法 根据 传递 过来 的 JSON 字符串 转换 为 User 对象, 从而 抛出 异常, 造成 调用 不成功。

       2. 如果请求参数是个对象,则使用@RequestBody注解,例:User register(@RequestBody User user);

四. 启动服务Consumer (假设现在有一个注册服务需要调用短信服务)

RegistService代码

@Service
public class RegistService {

  @Autowired
  private SmsApi  smsApi ;  //注入服务接口,实际注入的是OpenFeign框架通过字节码生成的包装类对象
    
    
  public void sendSmsCode(String mobile) {

        try {
          Result result = smsApi.sendMobileCode(mobile, bizType) ;  //调用服务
        } catch (AttemptLimitException e) {
            throw new UserCenterException(errorObj);
        }

    }

}

RegistController代码

@RestController
@RequestMapping(value = "/ecshop/api/1.0/registry")
public class RegistController {

    @Autowired
    private RegistService registService;

    // 发送验证码
    @RequestMapping(value = "/sendSmsCode", method = RequestMethod.GET)
    public Result sendSmsCode(String mobile) {

        //核对手机格式是否正确
        RegistUtils.checkMobileFormat(mobile);

        registService.sendSmsCode(mobile);

        return new Result(true, "R004", "发送验证码成功~", false);

    }
}

启动类

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class App {
    public static void main(String[] args) {
        SpringApplication.run(App.class, args);
    }
    
}

配置文件

spring: 
  application: 
    name: registerservices
server:
  tomcat: 
    uri-encoding: UTF-8
  port: 1001 
eureka:
  instance:
    appname: registerservices
    prefer-ip-address: true
  client:
    serviceUrl:
      defaultZone: http://eurekaServer1:8761/eureka/,http://eurekaServer2:8761/eureka/    //此处也可以只注册一个注册中心

五. 测试

   1. 通过浏览器访问 http://xxx/ecshop/api/1.0/registry

    2.通过单元测试方式

@RunWith(SpringRunner.class)
@SpringBootTest(classes = App.class)
public class RegistServiceTest {
    

    @Autowired
    private RegistService registService ;
    
    @Test
    public void sendSmsCode() {
        String mobile = "xxxx7222222" ;
        registService.sendSmsCode(mobile);
    }
    
原文地址:https://www.cnblogs.com/hzhuxin/p/10573348.html