这两年可以说微服务是热词,也是新领域,学习的成本也较高,基础东西太多比如什么Dubbo,zookeeper,Springboot等等。Dubbo也是实现服务治理又是阿里出的一套开源RPC框架,但是SpringCloud出现后便立即热火朝天,当然阿里也加入了SpringCloud的孵化。
什么是微服务,分布式?
分布式:不同的模块部署在不同的服务器上,可以更好的解决网站高并发。
微服务:架构设计概念,各服务间隔离(分布式也是隔离),自治(分布式依赖整体组合)其它特性(单一职责,边界,异步通信,独立部署)是分布式概念的跟严格执行 SOA到微服务架构的演进过程
。简单的说把项目拆分成各各模块,用注册中心的方式把服务都链接在一起
服务提供者与消费关系
服务提供者:提供服务被人调用
消费者:调用服务
今天我们说下SpringCloud的Eureka注册中心
官方:

group 'com.wang' version '1.0-SNAPSHOT' apply plugin: 'java' sourceCompatibility = 1.8 buildscript { ext {//定义一个变量,统一规定springboot的版本 springBootVersion = '1.5.10.RELEASE' } repositories { maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' } jcenter() mavenCentral() //Spring repo maven { url "http://repo.spring.io/snapshot" } maven { url "http://repo.spring.io/milestone" } maven { url "http://repo.spring.io/release" } maven { url 'http://repo.spring.io/plugins-snapshot' } } dependencies {//用来打包 classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") } } //设定当前所有的项目的配置 allprojects { group 'com.ssx' version '1.0-SNAPSHOT' ext { springCloudVersion = 'Edgware.SR2' } repositories { maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' } jcenter() mavenCentral() //Spring repo maven { url "http://repo.spring.io/snapshot" } maven { url "http://repo.spring.io/milestone" } maven { url "http://repo.spring.io/release" } maven { url 'http://repo.spring.io/plugins-snapshot' } } } //设定当前模块项目中的配置 subprojects { apply plugin: 'java' apply plugin: 'idea' apply plugin: 'spring-boot' dependencies { //使用springboot-web组件,但是排除tomcat组件 compile ('org.springframework.boot:spring-boot-starter-web'){ exclude module:"spring-boot-starter-tomcat" } //使用undertow作为应用服务,作为servlet容器 compile 'org.springframework.boot:spring-boot-starter-undertow' //使用健康检查组件 compile 'org.springframework.boot:spring-boot-starter-actuator' testCompile( group: 'junit', name: 'junit', version: '4.12' ) } dependencyManagement { imports { //加上此配置后,如果需要引用springcloud的组件,就不需要再提供版本信息 mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}" } } }
3.注册中心启动类
package org.gw.reigster.conter; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; /** * @DATA 2019-02-27 19:56 * @Author 张国伟 WeChat:17630376104 * @Description TODO */ @EnableEurekaServer #这个是表示这个项目作为euraka注册中心 @SpringBootApplication public class ReigsterConterProvider { public static void main(String[] args) { SpringApplication.run(ReigsterConterProvider.class,args); } }
4.注册中心yml
server: port: 8888 spring: application: name: reigster-conter eureka: client: register-with-eureka: false #启动时不注册 本来就是注册中心 表示自己是注册中心 fetch-registry: false #不向注册中心拉取数据 server: enable-self-preservation: false #关闭自我保护 测试环境用 生产环境一般不用
5.启动注册中心访问8888
这个为Eureka的信息页面 可以看到这个时候 Instances currently registered with Eureka里面是No instances available 也就是这个时候还没有服务注册进来,下面我们写注册方
这个模块为solr
package org.gw.solr; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; /** * @DATA 2019-02-27 20:38 * @Author 张国伟 WeChat:17630376104 * @Description TODO */ @EnableEurekaClient #这里为Eureka客户端也就是服务 @SpringBootApplication public class ProjectSolrProvider { public static void main(String[] args) { SpringApplication.run(ProjectSolrProvider.class, args); } }
yml
server: port: 10002 spring: application: name: project-solr eureka: client: service-url: defaultZone: http://localhost:8888/eureka/ instance: prefer-ip-address: true
这时候我们启动这个服务
这个时候可以看到 有个服务已经注册进来
这个就是实现了 注册也发现,那我们紧接这 如何实现服务与服务之间调用呢?我现在想project-shopping-mall模块的controller调用solr的controller如何实现呢
package org.gw.shopping.mall; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; import org.springframework.context.annotation.Bean; import org.springframework.web.client.RestTemplate; /** * @DATA 2019-02-27 20:24 * @Author 张国伟 WeChat:17630376104 * @Description TODO */ @EnableEurekaClient @SpringBootApplication public class ShoppingMallProvider { @LoadBalanced @Bean public RestTemplate resultTemplate() { RestTemplate template = new RestTemplate(); return template; } public static void main(String[] args) { SpringApplication.run(ShoppingMallProvider.class, args); } }
RestTemplate表示网络请求 在启动类里把他实例
package org.gw.shopping.mall.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate; /** * @DATA 2019-02-27 20:45 * @Author 张国伟 WeChat:17630376104 * @Description TODO */ @Controller public class ShopController { @Autowired private RestTemplate restTemplate; @RequestMapping("/toIndex") public String toIndex(Model model) { String msg = restTemplate.getForEntity("http://PROJECT-SOLR/solrSearc", String.class).getBody(); model.addAttribute("msg", msg); return "index"; } }
这个为调用solr的controller根据名字调用
package org.gw.solr.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * @DATA 2019-02-27 20:40 * @Author 张国伟 WeChat:17630376104 * @Description TODO */ @RestController public class SolrSearchController { @RequestMapping("/solrSearc") public String solrSearc(){ return "从solr查询到数据"; } }
意思就是说 我在shop里调用solr的controller他会返回一个从solr查询到数据
我们来尝试下
shop模块里有thymeleaf模板展示数据
<!DOCTYPE html>
<html lang="en" xmlxs:th="http://www.thymeleaf.org" xmlns:xmlxs="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8"/>
<title>Title</title>
</head >
<body>
<h1>欢迎进入商城</h1>
<h2>从solr微服务中查到的数据::::<span th:text="${msg}"></span></h2>
</body>
</html>
可以看到 已经成功拿到数据
到这里,我们已经实现服务的注册与发现,下章说 链路跟踪,有问题请及时评论。