概要
之前了解了很多的springboot的基础知识,现在实战下,做个微服务,什么是微服务呢?
就是按业务拆分模块,然后模块间通过restful或者rpc调用。
本文主要写
①一个服务端,一个客户端,服务端写个接口,客户端通过restful查询。
②加个注册中心:服务端把注册地址到给zookeeper,客户端通过zookeeper查询数据
③多个服务注册到zookeeper,实现负载均衡。
服务端代码地址:
https://github.com/hufanglei/springboot-v-study/tree/a-mall-product
关键代码展示:
/** * 服务注册 */ @Component public class ServiceRegister implements ApplicationRunner { @Value("${zookeeper.address}") private String zkAddress; @Override public void run(ApplicationArguments args) throws Exception { CuratorFramework client = CuratorFrameworkFactory.newClient(zkAddress, new RetryOneTime(1000)); client.start(); client.blockUntilConnected(); ServiceInstance<Object> instance = ServiceInstance.builder().name("product").address("192.168.157.1").port(8080).build(); ServiceDiscovery<Object> serviceDiscovery = ServiceDiscoveryBuilder .builder(Object.class) .client(client) .basePath("/soa").build(); serviceDiscovery.registerService(instance); serviceDiscovery.start(); System.out.println("service register ok"); } }
客户端代码地址:
https://github.com/hufanglei/springboot-v-study/tree/a-mall-product-web
关键代码展示:
最简单的resful版调用
public class Client { public static String BASE_URL ="http://127.0.0.1:8080"; public static void main(String[] args) { RestTemplate restTemplate = new RestTemplate(); Response object = restTemplate.getForObject(BASE_URL + "/soa/product/1", Response.class); System.out.println(new Gson().toJson(object)); String data = restTemplate.getForObject(BASE_URL + "/soa/product/1", String.class); System.out.println(data); System.out.println(new Gson().toJson(new Gson().fromJson(data, Response.class))); System.out.println(new Gson().toJson(new Gson().fromJson(data, Map.class).get("data"))); } }
zookeeper版调用
public class AMallProductWebApplication { public static String ZKADDRESS ="192.168.157.111:2181"; public static void main(String[] args) throws Exception { CuratorFramework client = CuratorFrameworkFactory.newClient(ZKADDRESS, new RetryOneTime(1000)); client.start(); client.blockUntilConnected(); ServiceDiscovery<Object> serviceDiscovery = ServiceDiscoveryBuilder .builder(Object.class) .client(client) .basePath("/soa").build(); Collection<ServiceInstance<Object>> list = serviceDiscovery.queryForInstances("product"); list.forEach((instance) ->{ System.out.println(instance.getAddress()); System.out.println(instance.getPort()); RestTemplate restTemplate = new RestTemplate(); Response resp = restTemplate.getForObject("http://"+instance.getAddress() +":"+instance.getPort() + "/soa/product/1", Response.class); System.out.println(resp.getCode()); System.out.println(resp.getMsg()); System.out.println(resp.getData()); }); } }
负载均衡+zookeeper版调用
/** * 轮询器 */ public class LoaderBalance { private int index = 0; private List<String> services; public LoaderBalance(List<String> services) { this.services = services; } public String choose(){ String service = services.get(index); index++; if(index >= services.size()){ index = 0; } return service; } }
public class AppBanlance { public static String ZKADDRESS ="192.168.157.111:2181"; public static void main(String[] args) throws Exception { CuratorFramework client = CuratorFrameworkFactory.newClient(ZKADDRESS, new RetryOneTime(1000)); client.start(); client.blockUntilConnected(); ServiceDiscovery<Object> serviceDiscovery = ServiceDiscoveryBuilder .builder(Object.class) .client(client) .basePath("/soa").build(); Collection<ServiceInstance<Object>> list = serviceDiscovery.queryForInstances("product"); final List<String> services = new ArrayList<>(); list.forEach((instance) ->{ services.add(instance.getAddress() + ":" + instance.getPort()); }); System.out.println(services); LoaderBalance lb = new LoaderBalance(services); for (int i=0;i<10;i++){ RestTemplate restTemplate = new RestTemplate(); Response resp = restTemplate.getForObject("http://"+lb.choose()+ "/soa/product/1", Response.class); System.out.println(resp.getCode()); System.out.println(resp.getMsg()); System.out.println(resp.getData()); } } }