案例中有三个角色:服务注册中心、服务提供者、服务消费者,其中服务注册中心就是我们上一篇的eureka单机版启动既可,流程是首先启动注册中心,服务提供者生产服务并注册到服务中心中,消费者从服务中心中获取服务并执行。

注册中心

上一篇文章中已经有注册中心的工程搭建。

服务提供者

添加依赖

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

启动类添加注册发现注解

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@SpringBootApplication
@EnableDiscoveryClient //注册发现注解
public class ProviderApplication {

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

配置文件

#服务端口
server.port=8010
#服务名
spring.application.name=cloud-provider

#指定服务注册中心的位置
eureka.client.serviceUrl.defaultZone=http://localhost:8000/eureka/

service

import com.uv.provider.entity.User;
import java.util.ArrayList;
import java.util.List;
import org.springframework.stereotype.Service;

/*
 * @author uv
 * @date 2018/10/8 14:46
 * 
 */
@Service
public class UserService {

    private static List<User> userList = null;
    //模拟数据库数据
    static {
        userList = new ArrayList<>();
        User user1 = new User();
        User user2 = new User();
        User user3 = new User();
        user1.setId(1).setName("Tom").setSex("男").setAge(18);
        user2.setId(2).setName("Sam").setSex("男").setAge(19);
        user3.setId(3).setName("Ling").setSex("女").setAge(18);
        userList.add(user1);
        userList.add(user2);
        userList.add(user3);
    }

    public List<User> getUserList() {
        return userList;
    }
    public User getUser(int id) {
        for (User user : userList) {
            if(user.getId() == id) {
                return user;
            }
        }
        return null;
    }
}

 User

/*
 * @author uv
 * @date 2018/10/8 14:47
 *
 */

public class User {
    private Integer id;
    private String name;
    private String sex;
    private Integer age;

    public Integer getId() {
        return id;
    }

    public User setId(Integer id) {
        this.id = id;
        return this;
    }

    public String getName() {
        return name;
    }

    public User setName(String name) {
        this.name = name;
        return this;
    }

    public String getSex() {
        return sex;
    }

    public User setSex(String sex) {
        this.sex = sex;
        return this;
    }

    public Integer getAge() {
        return age;
    }

    public User setAge(Integer age) {
        this.age = age;
        return this;
    }
}

 controller

import com.uv.provider.entity.User;
import com.uv.provider.service.UserService;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

/*
 * @author uv
 * @date 2018/10/8 15:26
 *
 */
@RestController
public class UserController {

    @Autowired
    private UserService userService;

    @GetMapping("user/list")
    public List<User> getUserList() {
        return userService.getUserList();
    }
    @GetMapping("user/{id}")
    public User getUserByPath(@PathVariable("id") int id) {
      return userService.getUser(id);
    }
    @GetMapping("user")
    public User getUserById(int id) {
        return userService.getUser(id);
    }
}

服务消费者

添加依赖

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

启动类添加注册发现注解和远程调用注解

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.feign.EnableFeignClients;

@SpringBootApplication
@EnableDiscoveryClient //启用服务注册与发现
@EnableFeignClients //启用feign进行远程调用
public class ConsumerApplication {

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

配置文件

Ribbon进行客户端负载均衡的Client并不是在服务启动的时候就初始化好的,而是在调用的时候才会去创建相应的Client,所以第一次调用的耗时不仅仅包含发送HTTP请求的时间,还包含了创建RibbonClient的时间,这样一来如果创建时间速度较慢,同时设置的超时时间又比较短的话,很容易就会出现成功启动的时候第一次访问会有报错的情况发生,但是之后又恢复正常访问的问题。使用饥饿加载模式,在服务启动时就会加载服务。

#服务端口
server.port=8020
#服务名
spring.application.name=cloud-consumer

#指定服务注册中心的位置
eureka.client.serviceUrl.defaultZone=http://localhost:8000/eureka/

#开启Ribbon的饥饿加载模式
ribbon.eager-load.enabled=true
#指定需要饥饿加载的服务名
ribbon.eager-load.clients=cloud-provider

#Fegin 连接超时,默认的ReadTimeout时间为5s,ConnectTimeout时间为2s
ribbon.ReadTimeout=60000
ribbon.ConnectTimeout=60000

 Client:远程调用   (远程调用返回的类必须有无参构造方法,否则报错:com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of com.uv.consumer.entity.User: no suitable constructor found, can not deserialize from Object value)

import com.uv.consumer.entity.User;
import java.util.List;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

/*
 * @author uv
 * @date 2018/10/8 18:48
 * 注意:远程调用返回的类(User)必须有无参构造方法,否则报错
 */

//name 为调用服务的spring.application.name
@FeignClient(name = "cloud-provider")
public interface UserClient {

    //不能使用组合注解,如GetMapping
    @RequestMapping(value = "user/list", method = RequestMethod.GET)
    List<User> getUserList();

    @RequestMapping(value = "user/{id}", method = RequestMethod.GET)
    User getUserByPath(@PathVariable("id") int id);

    //使用参数时,必须用@RequestParam注解
    @RequestMapping(value = "user", method = RequestMethod.GET)
    User getUserById(@RequestParam("id") int id);
}

  测试controller

import com.uv.consumer.entity.User;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/*
 * @author uv
 * @date 2018/10/8 19:00
 *
 */
@RestController
public class controller {

    @Autowired
    private UserClient userClient;

    @RequestMapping("test")
    public void test() {
        List<User> userList = userClient.getUserList();
        System.out.println(userList.size());
        User userById = userClient.getUserById(2);
        System.out.println(userById.getName());
        User userByPath = userClient.getUserByPath(3);
        System.out.println(userByPath.getName());
    }

}

依次启动eureka、provider、consumer服务,通过http://localhost:8000/ 可以看到,provider和consumer已经注册到Eureka中。

  

springcloud服务注册方式 springcloud如何注册服务_User

使用  http://localhost:8020/test 进行测试,结果如下,远程调用成功。

 

springcloud服务注册方式 springcloud如何注册服务_spring_02

github实例代码:https://github.com/UVliuwei/springcloud-demo