摘要:下一篇介紹基于的服務(wù)注冊(cè)與調(diào)用。服務(wù)提供者工程配置這里服務(wù)提供者是使用之前進(jìn)階教程第三篇整合連接池以及監(jiān)控改造而來,這里一樣的部分就不再重復(fù)說明,下面將說明新增的部分。
Spring Cloud簡(jiǎn)介
Spring Cloud是一個(gè)基于Spring Boot實(shí)現(xiàn)的云應(yīng)用開發(fā)工具,它為基于JVM的云應(yīng)用開發(fā)中涉及的配置管理、服務(wù)發(fā)現(xiàn)、斷路器、智能路由、微代理、控制總線、全局鎖、決策競(jìng)選、分布式會(huì)話和集群狀態(tài)管理等操作提供了一種簡(jiǎn)單的開發(fā)方式。
Spring Cloud包含了多個(gè)子項(xiàng)目(針對(duì)分布式系統(tǒng)中涉及的多個(gè)不同開源產(chǎn)品),比如:Spring Cloud Config、Spring Cloud Netflix、Spring Cloud CloudFoundry、Spring Cloud AWS、Spring Cloud Security、Spring Cloud Commons、Spring Cloud Zookeeper、Spring Cloud CLI等項(xiàng)目。
微服務(wù)架構(gòu)“微服務(wù)架構(gòu)”在這幾年非常的火熱,以至于關(guān)于微服務(wù)架構(gòu)相關(guān)的開源產(chǎn)品被反復(fù)的提及(比如: netflix、dubbo),Spring Cloud也因Spring社區(qū)的強(qiáng)大知名度和影響力也被廣大架構(gòu)師與開發(fā)者備受關(guān)注。
那么什么是“微服務(wù)架構(gòu)”呢?簡(jiǎn)單的說,微服務(wù)架構(gòu)就是將一個(gè)完整的應(yīng)用從數(shù)據(jù)存儲(chǔ)開始垂直拆分成多個(gè)不同的服務(wù),每個(gè)服務(wù)都能獨(dú)立部署、獨(dú)立維護(hù)、獨(dú)立擴(kuò)展,服務(wù)與服務(wù)間通過諸如RESTful API的方式互相調(diào)用。
對(duì)于“微服務(wù)架構(gòu)”,大家在互聯(lián)網(wǎng)可以搜索到很多相關(guān)的介紹和研究文章來進(jìn)行學(xué)習(xí)和了解。也可以閱讀始祖Martin Fowler的《Microservices》(中文版翻譯點(diǎn)擊查看),本文不做更多的介紹和描述。
服務(wù)治理在簡(jiǎn)單介紹了Spring Cloud和微服務(wù)架構(gòu)之后,下面回歸本文的主旨內(nèi)容,如何使用Spring Cloud來實(shí)現(xiàn)服務(wù)治理。
由于Spring Cloud為服務(wù)治理做了一層抽象接口,所以在Spring Cloud應(yīng)用中可以支持多種不同的服務(wù)治理框架,比如:Netflix Eureka、Consul、Zookeeper。在Spring Cloud服務(wù)治理抽象層的作用下,我們可以無縫地切換服務(wù)治理實(shí)現(xiàn),并且不影響任何其他的服務(wù)注冊(cè)、服務(wù)發(fā)現(xiàn)、服務(wù)調(diào)用等邏輯。
所以,下面我們通過Eureka這種種服務(wù)治理的實(shí)現(xiàn)來體會(huì)Spring Cloud這一層抽象所帶來的好處。
下一篇介紹基于Consul的服務(wù)注冊(cè)與調(diào)用。
首先,我們來嘗試使用Spring Cloud Eureka來實(shí)現(xiàn)服務(wù)治理。
Spring Cloud Eureka是Spring Cloud Netflix項(xiàng)目下的服務(wù)治理模塊。而Spring Cloud Netflix項(xiàng)目是Spring Cloud的子項(xiàng)目之一,主要內(nèi)容是對(duì)Netflix公司一系列開源產(chǎn)品的包裝,它為Spring Boot應(yīng)用提供了自配置的Netflix OSS整合。通過一些簡(jiǎn)單的注解,開發(fā)者就可以快速的在應(yīng)用中配置一下常用模塊并構(gòu)建龐大的分布式系統(tǒng)。它主要提供的模塊包括:服務(wù)發(fā)現(xiàn)(Eureka),斷路器(Hystrix),智能路由(Zuul),客戶端負(fù)載均衡(Ribbon)等。
下面,就來具體看看如何使用Spring Cloud Eureka實(shí)現(xiàn)服務(wù)治理,這里使用eureka-server為服務(wù)注冊(cè)中心工程、eureka-provider服務(wù)提供者工程、eureka-consumer服務(wù)消費(fèi)者工程。
準(zhǔn)備工作環(huán)境:
windows jdk 8 maven 3.0 IDEA構(gòu)建工程
首先構(gòu)建父工程,引入父工程依賴:
4.0.0 cn.zhangbox spring-cloud-study 1.0-SNAPSHOT cn.zhangbox spring-cloud-eureka pom 1.0-SNAPSHOT eureka-server eureka-provider eureka-consumer
父工程取名為:spring-cloud-eureka
構(gòu)建子工程,分別創(chuàng)建工程名為:eureka-server、eureka-provider、eureka-consumer并在pom中加入以下依賴:
4.0.0 cn.zhangbox spring-cloud-eureka 1.0-SNAPSHOT cn.zhangbox eureka-server 1.0.0 jar eureka-server Spring Cloud In Action UTF-8 1.8 org.springframework.cloud spring-cloud-starter-eureka-server org.springframework.cloud spring-cloud-dependencies Dalston.SR1 pom import org.springframework.boot spring-boot-maven-plugin
4.0.0 cn.zhangbox spring-cloud-eureka 1.0-SNAPSHOT cn.zhangbox eureka-provider 0.0.1-SNAPSHOT jar eureka-provider this project for Spring Boot UTF-8 UTF-8 1.8 3.4 1.10 1.2.0 1.16.14 1.2.41 1.1.2 aliyunmaven http://maven.aliyun.com/nexus/content/groups/public/ org.mybatis.spring.boot mybatis-spring-boot-starter ${mybatis-spring-boot.version} org.springframework.cloud spring-cloud-starter-eureka org.springframework.boot spring-boot-starter-web io.springfox springfox-swagger2 2.6.1 io.springfox springfox-swagger-ui 2.6.1 mysql mysql-connector-java runtime org.springframework.boot spring-boot-starter-test test org.apache.commons commons-lang3 ${commons-lang3.version} commons-codec commons-codec ${commons-codec.version} com.alibaba fastjson ${fastjson.version} com.alibaba druid-spring-boot-starter ${druid.version} org.projectlombok lombok ${lombok.version} org.springframework.cloud spring-cloud-dependencies Dalston.SR1 pom import eureka-provider org.springframework.boot spring-boot-maven-plugin
4.0.0 cn.zhangbox spring-cloud-eureka 1.0-SNAPSHOT cn.zhangbox eureka-consumer 0.0.1-SNAPSHOT jar eureka-consumer this project for Spring Boot UTF-8 UTF-8 1.8 3.4 1.10 1.2.0 1.16.14 1.2.41 1.1.2 aliyunmaven http://maven.aliyun.com/nexus/content/groups/public/ org.springframework.cloud spring-cloud-starter-eureka org.springframework.cloud spring-cloud-starter-feign org.springframework.boot spring-boot-starter-web io.springfox springfox-swagger2 2.6.1 io.springfox springfox-swagger-ui 2.6.1 org.springframework.boot spring-boot-starter-test test org.apache.commons commons-lang3 ${commons-lang3.version} commons-codec commons-codec ${commons-codec.version} com.alibaba fastjson ${fastjson.version} org.projectlombok lombok ${lombok.version} org.springframework.cloud spring-cloud-dependencies Dalston.SR1 pom import eureka-provider org.springframework.boot spring-boot-maven-plugin
工程構(gòu)建完成。
服務(wù)注冊(cè)中心工程配置首先:在eureka-server工程下resource目錄下添加application.yml文件并加入以下配置:
#工程名稱 spring: application: name: eureka-server #選擇哪一個(gè)環(huán)境的配置 #這里可以在每個(gè)環(huán)境配置redis,數(shù)據(jù)庫(mysql),消息(kafka)等相關(guān)的組件的配置 profiles: active: dev #配置eureka注冊(cè)中心 eureka: #server: #配置關(guān)閉自我保護(hù)模式 #enableSelfPreservation: false #配置Eureka Server清理無效節(jié)點(diǎn)的時(shí)間間隔 #eviction-interval-timer-in-ms: 4000 instance: #配置與此實(shí)例相關(guān)聯(lián)的主機(jī)名,是其他實(shí)例可以用來進(jìn)行請(qǐng)求的準(zhǔn)確名稱 hostname: eureka-server #顯示服務(wù)ip地址 preferIpAddress: true #獲取服務(wù)的ip和端口 instanceId: ${spring.cloud.client.ipAddress}:${server.port} client: #配置不將自己注冊(cè)到eureka注冊(cè)中心 register-with-eureka: false #配置此客戶端不獲取eureka服務(wù)器注冊(cè)表上的注冊(cè)信息 fetch-registry: false serviceUrl: #配置默認(rèn)節(jié)點(diǎn)有信息,這里是獲取本機(jī)的ip和端口來實(shí)現(xiàn),如果不配置,默認(rèn)會(huì)找8761端口,這里配置的是1001端口,因此會(huì)報(bào)錯(cuò) defaultZone: http://${spring.cloud.client.ipAddress}:${server.port}/eureka/ #文檔塊區(qū)分為三個(gè)--- --- server: port: 1001 spring: profiles: dev #日志 logging: config: classpath:log/logback.xml path: log/eureka-server #文檔塊區(qū)分為三個(gè)--- --- server: port: 1002 spring: profiles: test #日志 logging: config: classpath:log/logback.xml path: usr/eureka-server/log/eureka-server #文檔塊區(qū)分為三個(gè)--- --- server: port: 1003 spring: profiles: prod #日志 logging: config: classpath:log/logback.xml path: usr/eureka-server/log/eureka-server
這里日志的配置不在詳細(xì)說明,不知道怎么配置可以參考這篇文章:
SpringBoot進(jìn)階教程 | 第二篇:日志組件logback實(shí)現(xiàn)日志分級(jí)打印
其次:創(chuàng)建核心啟動(dòng)類:
@EnableEurekaServer//加上此注解表示將此工程啟動(dòng)后為注冊(cè)中心 @SpringBootApplication public class EurekaServerApplication { public static void main(String[] args) { new SpringApplicationBuilder(EurekaServerApplication.class).web(true).run(args); } }
最后:啟動(dòng)項(xiàng)目
至此eureka注冊(cè)中心創(chuàng)建完成,瀏覽器輸入地址:http://localhost:1001/
可以看到如下頁面,表示服務(wù)啟動(dòng)OK
這里這看到還沒有服務(wù)暴露出來,是因?yàn)檫€沒創(chuàng)建服務(wù)提供者工程。
這里服務(wù)提供者是使用之前SpringBoot進(jìn)階教程 | 第三篇:整合Druid連接池以及Druid監(jiān)控改造而來,這里一樣的部分就不再重復(fù)說明,下面將說明新增的部分。
首先:修改application.yml配置為如下:
#公共配置 server: port: 80 tomcat: uri-encoding: UTF-8 spring: application: #服務(wù)名稱,更關(guān)鍵,使用feign進(jìn)行服務(wù)消費(fèi)將以此為依據(jù) name: eureka-provider #激活哪一個(gè)環(huán)境的配置文件 profiles: active: dev #連接池配置 datasource: driver-class-name: com.mysql.jdbc.Driver # 使用druid數(shù)據(jù)源 type: com.alibaba.druid.pool.DruidDataSource druid: # 配置測(cè)試查詢語句 validationQuery: SELECT 1 FROM DUAL # 初始化大小,最小,最大 initialSize: 10 minIdle: 10 maxActive: 200 # 配置一個(gè)連接在池中最小生存的時(shí)間,單位是毫秒 minEvictableIdleTimeMillis: 180000 testOnBorrow: false testWhileIdle: true removeAbandoned: true removeAbandonedTimeout: 1800 logAbandoned: true # 打開PSCache,并且指定每個(gè)連接上PSCache的大小 poolPreparedStatements: true maxOpenPreparedStatements: 100 # 配置監(jiān)控統(tǒng)計(jì)攔截的filters,去掉后監(jiān)控界面sql無法統(tǒng)計(jì),"wall"用于防火墻 filters: stat,wall,log4j # 通過connectProperties屬性來打開mergeSql功能;慢SQL記錄 connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000 #配置eureka獲取服務(wù)地址,這里使用的是本地注冊(cè)中心 eureka: client: serviceUrl: defaultZone: http://localhost:1001/eureka/ #配置Swagger相關(guān)信息 instance: prefer-ip-address: true instanceId: ${spring.cloud.client.ipAddress}:${server.port} status-page-url: http://${spring.cloud.client.ipAddress}:${server.port}/swagger-ui.html # ${server.port}為該服務(wù)的端口號(hào) #mybatis mybatis: # 實(shí)體類掃描 type-aliases-package: cn.zhangbox.springboot.entity # 配置映射文件位置 mapper-locations: classpath:mapper/*.xml # 開啟駝峰匹配 mapUnderscoreToCamelCase: true --- #開發(fā)環(huán)境配置 server: #端口 port: 8080 spring: profiles: dev # 數(shù)據(jù)源配置 datasource: url: jdbc:mysql://101.132.66.175:3306/student?useUnicode=true&characterEncoding=utf8&useSSL=false&tinyInt1isBit=true username: root password: 123456 #日志 logging: config: classpath:log/logback.xml path: log/eureka-provider --- #測(cè)試環(huán)境配置 server: #端口 port: 80 spring: profiles: test # 數(shù)據(jù)源配置 datasource: url: jdbc:mysql://127.0.0.1:3306/eureka-provider?useUnicode=true&characterEncoding=utf8&useSSL=false&tinyInt1isBit=true username: root password: 123456 #日志 logging: config: classpath:log/logback.xml path: /home/log/eureka-provider --- #生產(chǎn)環(huán)境配置 server: #端口 port: 8080 spring: profiles: prod # 數(shù)據(jù)源配置 datasource: url: jdbc:mysql://127.0.0.1:3306/eureka-provider?useUnicode=true&characterEncoding=utf8&useSSL=false&tinyInt1isBit=true username: root password: 123456 #日志 logging: config: classpath:log/logback.xml path: /home/log/eureka-provider
其次:在config目錄下增加SwaggerConfig類加入以下代碼:
@Configuration @EnableSwagger2 public class SwaggerConfig { @Bean public Docket userApi() { Docket docket = new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) .select() .apis(RequestHandlerSelectors.basePackage("cn.zhangbox.eureka.provider.controller"))//過濾的接口,有這掃描才會(huì)看到接口信息 .paths(PathSelectors.any()) .build(); return docket; } private ApiInfo apiInfo() { return new ApiInfoBuilder().title("eureka服務(wù)端提供者接口平臺(tái)").description("服務(wù)相關(guān)數(shù)據(jù)接口") .termsOfServiceUrl("http://www.zhang.box.cn/").contact("技術(shù)開發(fā)部") .license("Licence Version 1.0").licenseUrl("#").version("1.0").build(); } }
這里如果不會(huì)使用swagger的整合可以參考這篇文章:
SpringBoot非官方教程 | 第十一篇:SpringBoot集成swagger2,構(gòu)建優(yōu)雅的Restful API
接著:創(chuàng)建核心啟動(dòng)類:
@EnableDiscoveryClient //使用該注解將注冊(cè)服務(wù)到eureka @SpringBootApplication @MapperScan("cn.zhangbox.eureka.provider.dao")//配置mybatis接口包掃描 public class EurekaProviderApplication extends SpringBootServletInitializer { public static void main(String[] args) { SpringApplication.run(EurekaProviderApplication.class, args); } }
最后:啟動(dòng)項(xiàng)目
至此eureka-provider服務(wù)提供者創(chuàng)建完成,瀏覽器輸入地址:http://localhost:1001/
可以看到如下頁面,表示服務(wù)注冊(cè)O(shè)K
點(diǎn)擊Status下的ip后可以跳轉(zhuǎn)看到swagger的頁面并可是測(cè)試服務(wù)提供者的接口,如下:
這里構(gòu)建的工程名為eureka-consumer,上文已經(jīng)構(gòu)建了工程但是沒有創(chuàng)建目錄,這里只需要在java目錄下創(chuàng)建config、controller,service,包即可,這里服務(wù)的消費(fèi)是通過feign來進(jìn)行服務(wù)調(diào)用的,后面會(huì)有專門以篇文章來講feign。
首先:在eureka-consumer工程下resource目錄下添加application.yml文件并加入以下配置:
#公共配置 server: port: 80 tomcat: uri-encoding: UTF-8 spring: #服務(wù)名稱,更關(guān)鍵,使用feign進(jìn)行服務(wù)消費(fèi)將以此為依據(jù) application: name: eureka-consumer #激活哪一個(gè)環(huán)境的配置文件 profiles: active: dev #配置eureka獲取服務(wù)地址,這里使用的是本地注冊(cè)中心 eureka: client: serviceUrl: defaultZone: http://localhost:1001/eureka/ #配置instance相關(guān)信息 instance: prefer-ip-address: true instanceId: ${spring.cloud.client.ipAddress}:${server.port} status-page-url: http://${spring.cloud.client.ipAddress}:${server.port}/swagger-ui.html # ${server.port}為該服務(wù)的端口號(hào) --- #開發(fā)環(huán)境配置 server: #端口 port: 8081 spring: profiles: dev #日志 logging: config: classpath:log/logback.xml path: log/eureka-consumer --- #測(cè)試環(huán)境配置 server: #端口 port: 8082 spring: profiles: test #日志 logging: config: classpath:log/logback.xml path: /home/log/eureka-consumer --- #生產(chǎn)環(huán)境配置 server: #端口 port: 8083 spring: profiles: prod #日志 logging: config: classpath:log/logback.xml path: /home/log/eureka-consumer
其次:在config目錄下增加SwaggerConfig類加入以下代碼:
@Configuration @EnableSwagger2 public class SwaggerConfig { @Bean public Docket userApi() { Docket docket = new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) .select() .apis(RequestHandlerSelectors.basePackage("cn.zhangbox.eureka.consumer.controller"))//過濾的接口,有這掃描才會(huì)看到接口信息 .paths(PathSelectors.any()) .build(); return docket; } private ApiInfo apiInfo() { return new ApiInfoBuilder().title("eureka服務(wù)端消費(fèi)者接口平臺(tái)").description("服務(wù)相關(guān)數(shù)據(jù)接口") .termsOfServiceUrl("http://www.zhang.box.cn/").contact("技術(shù)開發(fā)部") .license("Licence Version 1.0").licenseUrl("#").version("1.0").build(); } }
接著:在service包下創(chuàng)建StudentConsumerService類并加入以下代碼:
@FeignClient(value = "eureka-provider") public interface StudentConsumerService { /** * 查詢所有的學(xué)生信息 * * @param sname * @param age * @return */ @RequestMapping(value = "/student/list",method = RequestMethod.GET) String getStudentList(@RequestParam(value = "sname") String sname, @RequestParam(value = "age") Integer age); }
然后:在controller包下創(chuàng)建StudentConteroller并加入如下代碼:
@Controller @RequestMapping("/student") @Api(value = "eureka-consumer", description = "學(xué)生查詢接口") public class StudentConteroller { private static final Logger LOGGER = LoggerFactory.getLogger(StudentConteroller.class); @Autowired StudentConsumerService studentService; /** * 查詢所有的學(xué)生信息 * * @param sname * @param age * @param modelMap * @return */ @ResponseBody @GetMapping("/consumer/list") public String list( @ApiParam(value = "學(xué)生姓名") @RequestParam(required = false) String sname, @ApiParam(value = "年齡") @RequestParam(required = false) Integer age, ModelMap modelMap) { String json = null; try { json = studentService.getStudentList(sname, age); } catch (Exception e) { e.printStackTrace(); modelMap.put("ren_code", "0"); modelMap.put("ren_msg", "查詢失敗===>" + e); LOGGER.error("查詢失敗===>" + e); json = JSON.toJSONString(modelMap); } return json; } }
接著:創(chuàng)建核心啟動(dòng)類:
@EnableFeignClients//開啟Feign調(diào)用接口 @EnableDiscoveryClient//開啟客戶端服務(wù),沒有這個(gè)注解會(huì)報(bào)Feign找不到對(duì)應(yīng)服務(wù)的錯(cuò)誤 @SpringBootApplication public class EurekaConsumerApplication extends SpringBootServletInitializer { public static void main(String[] args) { SpringApplication.run(EurekaConsumerApplication.class, args); } }
最后:啟動(dòng)項(xiàng)目
至此eureka-consumer服務(wù)提供者創(chuàng)建完成,瀏覽器輸入地址:http://127.0.0.1:8081/swagger-ui.html
同樣也可以點(diǎn)擊eureka控制臺(tái)中Application為EUREKA-CONSUMER后Status下的ip后可以跳轉(zhuǎn)看到swagger的頁面并可是測(cè)試服務(wù)消費(fèi)者的接口,可以看到如下頁面,并點(diǎn)擊try it out按鈕,返回了正確的學(xué)生信息數(shù)據(jù)
返回?cái)?shù)據(jù)如下:
{ "ren_code": "0", "ren_msg": "查詢成功", "studentList": [{ "age": "17", "birth": "2010-07-22", "dept": "王同學(xué)學(xué)習(xí)成績(jī)很不錯(cuò)", "sex": "1", "sname": "王同學(xué)", "sno": 1 }, { "age": "17", "birth": "2010-07-22", "dept": "李同學(xué)學(xué)習(xí)成績(jī)很不錯(cuò)", "sex": "1", "sname": "李同學(xué)", "sno": 2 }] }
以上就是spring cloud基于eurka實(shí)現(xiàn)分布式服務(wù)注冊(cè)與消費(fèi)的整合流程,是不是很簡(jiǎn)單,你也來小試牛刀一把吧。
寫在最后歡迎關(guān)注、喜歡、和點(diǎn)贊后續(xù)將推出更多的spring cloud教程,敬請(qǐng)期待。
源碼地址SpringCloud核心教程 | 第三篇:服務(wù)注冊(cè)與發(fā)現(xiàn) Eureka篇
歡迎關(guān)注我的微信公眾號(hào)獲取更多更全的學(xué)習(xí)資源,視頻資料,技術(shù)干貨!
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/71640.html
摘要:接下來繼續(xù)介紹三種架構(gòu)模式,分別是查詢分離模式微服務(wù)模式多級(jí)緩存模式。分布式應(yīng)用程序可以基于實(shí)現(xiàn)諸如數(shù)據(jù)發(fā)布訂閱負(fù)載均衡命名服務(wù)分布式協(xié)調(diào)通知集群管理選舉分布式鎖和分布式隊(duì)列等功能。 SpringCloud 分布式配置 SpringCloud 分布式配置 史上最簡(jiǎn)單的 SpringCloud 教程 | 第九篇: 服務(wù)鏈路追蹤 (Spring Cloud Sleuth) 史上最簡(jiǎn)單的 S...
摘要:一簡(jiǎn)介是一個(gè)聲明式的服務(wù)客戶端,它使得寫服務(wù)變得更簡(jiǎn)單。同時(shí)支持可插拔的編碼器和解碼器。對(duì)添加了支持,同時(shí)在中次用相同的。 轉(zhuǎn)載請(qǐng)標(biāo)明出處: http://blog.csdn.net/forezp/a...本文出自方志朋的博客 上一篇文章,講述了通過restTemplate+ribbon去消費(fèi)服務(wù),這篇文章主要講述通過feign去消費(fèi)服務(wù)。 一、Feign簡(jiǎn)介 Feign是一個(gè)聲明式的...
閱讀 2438·2021-11-11 16:54
閱讀 2675·2021-09-26 09:47
閱讀 4014·2021-09-08 09:36
閱讀 2761·2021-07-25 21:37
閱讀 948·2019-08-30 15:54
閱讀 2563·2019-08-30 14:22
閱讀 3274·2019-08-30 13:57
閱讀 2681·2019-08-29 17:17