spring-cloud学习笔记基于spring-boot2.0.3--服务提供与调用

上一篇我们简单的介绍了注册中心Eureka的内容,这一篇我们接下来讲解的是服务的提供与调用。主要存在三种角色

1、注册中心

2、服务提供者提供服务并注册到注册中心

3、服务消费者从注册中心获取服务。

首先创建一个spring-boot项目vts_sc_provider。引入Maven配置

  	<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>

这里需要web的支持,所以引入web的jar包,注意这里引入的Eureka的jar包和注册中心引入的Jar包略有不同,是一个client的包。

新建Application启动类,直接用ide生成对应的main方法即可。

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

}

修改配置文件,指定注册中心和端口内容

spring:
  application:
    name: eureka-producer
eureka:
  client:
    service-url:
      defaultZone: http://47.95.250.218:9001/eureka/
server:
  port: 8001

新建Controller类,HelloController

@RestController
public class HelloControler {
	
	@GetMapping("/test")
	public String test(@RequestParam String name){
		return "我是"+name;
	}

}

然后启动项目:通过http://localhost:8001/test?name=大仙,进行访问这是可以进行提供服务的。

然后我们再次新建一个spring-boot项目vts_sc_consumer。引入相应的maven配置

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

      创建服务消费者根据使用 API 的不同,大致分为三种方式。虽然大家在实际使用中用的应该都是 Feign,但是这里还是把这三种都介绍一下吧,如果你只关心 Feign,可以直接跳到最后。

     设置配置文件内容:

spring:
  application:
    name: eureka-consumer
eureka:
  client:
    service-url:
      defaultZone: http://47.95.250.218:9001/eureka/
server:
  port: 8002

使用 LoadBalancerClient

LoadBalancerClient接口的命名中,我们就知道这是一个负载均衡客户端的抽象定义,下面我们就看看如何使用 Spring Cloud 提供的负载均衡器客户端接口来实现服务的消费。

修改启动类,初始化RestTemplate:

@SpringBootApplication
public class Application {
	@Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
	public static void main(String[] args) throws Exception {
		SpringApplication.run(Application.class, args);
	}
}

Controller

创建一个接口用来消费 eureka-producer 提供的接口:

@RequestMapping("/hello")
@RestController
public class HelloController {

    @Autowired
    private LoadBalancerClient client;

    @Autowired
    private RestTemplate restTemplate;

    @GetMapping("/")
    public String hello(@RequestParam String name) {
        name += "!";
        ServiceInstance instance = client.choose("eureka-producer");
        String url = "http://" + instance.getHost() + ":" + instance.getPort() + "/hello/?name=" + name;
        return restTemplate.getForObject(url, String.class);
    }

}

可以看到这里,我们注入了LoadBalancerClientRestTemplate,并在hello方法中,先通过loadBalancerClientchoose方法来负载均衡的选出一个eureka-producer的服务实例,这个服务实例的基本信息存储在ServiceInstance中,然后通过这些对象中的信息拼接出访问服务调用者的/hello/接口的详细地址,最后再利用RestTemplate对象实现对服务提供者接口的调用。

Spring Cloud Ribbon

当 Ribbon 与 Eureka 联合使用时,ribbonServerList 会被 DiscoveryEnabledNIWSServerList 重写,扩展成从 Eureka 注册中心中获取服务实例列表。同时它也会用 NIWSDiscoveryPing 来取代 IPing,它将职责委托给 Eureka 来确定服务端是否已经启动。

修改启动类,增加注解@LoadBalanced

@LoadBalanced
@Bean
public RestTemplate restTemplate() {
	return new RestTemplate();
}

Controller

修改 controller,去掉LoadBalancerClient,并修改相应的方法,直接用 RestTemplate发起请求

@GetMapping("/")
public String hello(@RequestParam String name) {
    name += "!";
    String url = "http://eureka-producer/hello/?name=" + name;
    return restTemplate.getForObject(url, String.class);
}

可能你已经注意到了,这里直接用服务名eureka-producer取代了之前的具体的host:port。那么这样的请求为什么可以调用成功呢?因为 Spring Cloud Ribbon 有一个拦截器,它能够在这里进行实际调用的时候,自动的去选取服务实例,并将这里的服务名替换成实际要请求的 IP 地址和端口,从而完成服务接口的调用。

Spring Cloud Feign

在实际工作中,我们基本上都是使用 Feign 来完成调用的。我们通过一个例子来展现 Feign 如何方便的声明对 eureka-producer 服务的定义和调用。

修改启动类:

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

新建一个Service类

@FeignClient(name = "eureka-producer")
public interface TestService {

	@GetMapping("/test/")
    String test(@RequestParam(value = "name") String name);
}

使用@FeignClient指定服务提供者,并且该类中的方法名和参数和远程服务提供者的controller保持一致。

新增TestController类:

@RestController
public class TestController {
	@Autowired
	TestService testService;

	/**
	 * 参数做路径GET请求
	 * @param name
	 * @return
	 */
    @GetMapping("/test/{name}")
    public String index(@PathVariable("name") String name) {
        return testService.test(name + "!");
    }
    /**
     * 参数不做路径GET请求
     * @param name
     * @return
     */
    @GetMapping("/test1")
    public String test1(String name) {
    	return testService.test(name + "!");
    }
    
    /**
     * POST请求
     * @param name
     * @return
     */
    @PostMapping("/pay/test2")
    public String postTest(@RequestParam("name")String name){
    	return testService.test(name + "!");
    }

}

启动应用进行访问:http://localhost:8002/test1?name=%E5%A4%A7%E4%BB%99 成功返回。

猜你喜欢

转载自blog.csdn.net/zhuwei_clark/article/details/82150145