springcloud教程第2篇:服务消费者的两种创建方式

springcloud教程第2篇:服务消费者的两种创建方式

1、Ribbon + RestTemplate

1.1 准备工作:

​ 创建一个端口为8761的注册中心:具体创建方法

​ pom.xml需引入依赖: eureka-server

​ main程序加入注解@EnableEurekaServer

​ application.properties:

eureka.client.service-uri.default-zone =  http://localhost:8761/eureka/
eureka.client.还有registry-with-eureka和fetch....
server.port = 8761

这样就搭建好了你的注册中心了。

接下来创建服务提供者:

pom.xml需引入:eureka-client

main程序:

@SpringBootApplication
@EnableEurekaClient
@RestController
public class ServiceHiApplication {

    public static void main(String[] args) {
        SpringApplication.run(ServiceHiApplication.class, args);
    }

    @Value("${server.port}")
    String port;
    @RequestMapping("/hi")
    public String home(@RequestParam String name) {
        return "hi "+name+",i am from port:" +port;
    }

}

仅仅@EnableEurekaClient是不够的,还需要在配置文件中注明自己的服务注册中心的地址,application.yml配置文件如下:

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/
server:
  port: 8762
spring:
  application:
    name: service-hi                

依次打开Eureka-server、服务提供者,就发现 一个服务已经注册在服务中了,服务名为SERVICE-HI ,端口为8762

这时打开 http://localhost:8762/hi?name=yourname,你会在浏览器上看到 :

hi yourname,i am from port:8762

注:改变配置文件的端口在进行运行,会发现有2个除了端口不一样的其余一样的服务提供者,这就是微服务的高可用。

1.2创建服务消费者:

重新新建一个spring-boot工程,取名为:service-ribbon; 在它的pom.xml文件分别引入起步依赖spring-cloud-starter-eureka、spring-cloud-starter-ribbon、spring-boot-starter-web,代码如下:

pom.xml

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

application.yml:

#注册服务到注册中心
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/
      #端口
server:
  port: 8764
  #在注册中心的注册的名字
spring:
  application:
    name: service-ribbon

在工程的启动类中,通过@EnableDiscoveryClient向服务中心注册;并且向程序的ioc注入一个bean: restTemplate;并通过@LoadBalanced注解表明这个restRemplate开启负载均衡的功能。

@SpringBootApplication
@EnableDiscoveryClient
public class ServiceRibbonApplication {

    public static void main(String[] args) {
        SpringApplication.run(ServiceRibbonApplication.class, args);
    }

    @Bean
    //开启负载均衡Ribbon
    @LoadBalanced
    RestTemplate restTemplate() {
        return new RestTemplate();
    }

}

写一个测试类HelloService,通过之前注入ioc容器的restTemplate来消费service-hi服务的“/hi”接口,在这里我们直接用的程序名替代了具体的url地址,在ribbon中它会根据服务名来选择具体的服务实例,根据服务实例在请求的时候会用具体的url替换掉服务名,代码如下:

@Service
public class HelloService {

    @Autowired
    RestTemplate restTemplate;

    public String hiService(String name) {
        //这里调用restTemplate的getForObject获取http://SERVICE-HI/hi?name=接口返回的对象
        //restTemplate还有很多get方法,各位有兴趣的可以研究一下比如getForEntity(uri,Object)
        return restTemplate.getForObject("http://SERVICE-HI/hi?name="+name,String.class);
    }

}

写一个controller,在controller中用调用HelloService 的方法,代码如下:

@RestController
public class HelloControler {

    @Autowired
    HelloService helloService;
    @RequestMapping(value = "/hi")
    public String hi(@RequestParam String name){
        return helloService.hiService(name);
    }


}

在浏览器上多次访问http://localhost:8764/hi?name=fd,浏览器交替显示:

hi fd,i am from port:8762

hi fd,i am from port:8763

这说明当我们通过调用restTemplate.getForObject(“http://SERVICE-HI/hi?name=”+name,String.class)方法时,已经做了负载均衡,访问了不同的端口的服务实例。(main程序的RestTemplate上方的@LoadBalance注解)

此时,微服务的架构为:

此时架构图.png

  • 一个服务注册中心,eureka server,端口为8761
  • service-hi工程跑了两个实例,端口分别为8762,8763,分别向服务注册中心注册
  • sercvice-ribbon端口为8764,向服务注册中心注册
  • 当sercvice-ribbon通过restTemplate调用service-hi的hi接口时,因为用ribbon进行了负载均衡,会轮流的调用service-hi:8762和8763 两个端口的hi接口;

2、Feign

以上就是Ribbon+RestTemplate实现服务消费者的一个小demo

那什么是Feign呢?

2.1 feign简介

Feign是一个声明式的伪Http客户端,它使得写Http客户端变得更简单。使用Feign,只需要创建一个接口并注解。它具有可插拔的注解特性,可使用Feign 注解和JAX-RS注解。Feign支持可插拔的编码器和解码器。Feign默认集成了Ribbon,并和Eureka结合,默认实现了负载均衡的效果。

简而言之:

  • Feign 采用的是基于接口的注解
  • Feign 整合了ribbon

2.2 准备工作

继续用上一节的工程, 启动eureka-server,端口为8761; 启动service-hi 两次,端口分别为8762 、8763.

2.3、创建一个feign的服务

新建一个spring-boot工程,取名为service-feign,在它的pom文件引入Feign的起步依赖spring-cloud-starter–netflix-openfeign、Eureka的起步依赖spring-cloud-starter-netflix-eureka、Web的起步依赖spring-boot-starter-web,代码如下:

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

springcloud版本用最新的

在工程的配置文件application.yml文件,指定程序名为service-feign,端口号为8765,服务注册地址为http://localhost:8761/eureka/ ,代码如下:

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/
server:
  port: 8765
spring:
  application:
    name: service-feign

在程序的启动类ServiceFeignApplication ,加上@EnableFeignClients注解开启Feign的功能:

@SpringBootApplication
@EnableDiscoveryClient
//开启feign客户端
@EnableFeignClients
public class ServiceFeignApplication {

    public static void main(String[] args) {
        SpringApplication.run(ServiceFeignApplication.class, args);
    }
}

定义一个feign接口,通过@ FeignClient(value= “服务名”),来指定调用哪个服务。比如在代码中调用了service-hi服务的“/hi”接口,代码如下:

@FeignClient(value = "service-hi")
public interface SchedualServiceHi {
    @RequestMapping(value = "/hi",method = RequestMethod.GET)
    String sayHiFromClientOne(@RequestParam(value = "name") String name);
}

在controller层,对外暴露一个”/hi”的API接口,通过上面定义的Feign客户端SchedualServiceHi 来消费服务。代码如下:

@RestController
public class HiController {

    @Autowired
    SchedualServiceHi schedualServiceHi;
    @RequestMapping(value = "/hi",method = RequestMethod.GET)
    public String sayHi(@RequestParam String name){
        return schedualServiceHi.sayHiFromClientOne(name);
    }
}

启动程序,多次访问http://localhost:8765/hi?name=jd,浏览器交替显示:

hi jd,i am from port:8762

hi jd,i am from port:8763

3、参考资料


Author: Juntech
Reprint policy: All articles in this blog are used except for special statements CC BY 4.0 reprint polocy. If reproduced, please indicate source Juntech !
评论
  TOC