javascript
SpringCloud 单Eureka简单例子consumer-provider
SpringCloud
版本選擇
建議使用F或G開頭的
創(chuàng)建項目需要的工作
-
maven設置打包方式
-
導入依賴文本
-
SpringCloud,provider和consumer都需要加spring-cloud包,并且要設置
- <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>Greenwich.SR3</version><type>pom</type><scope>runtime</scope> </dependency>
-
web
-
數(shù)據(jù)庫之類包
-
熱部署
-
- create table dept (deptno bigint auto_increment,dname varchar(60) null,db_source varchar(60) null,constraint dept_pkprimary key (deptno) )character set utf8 collate utf8_general_ci;
- use db01;
insert into dept ( dname, db_source)
values ('開發(fā)部',database());
?
provider和consumer例子
provider
搭建一個基礎環(huán)境springboot+mybatis+druid
-
遇到一個bug,打包錯誤
-
提示說無法配置數(shù)據(jù)源,但是跟數(shù)據(jù)源并沒有什么關系,掃描不到數(shù)據(jù)源的問題,因為跟視頻做,pom的作用是maven分項目管理,需要有一個父項目
-
所以會導致配置失敗的問題
-
經(jīng)過這次試錯
-
先確保導入maven包是沒問題的
-
更改了pom啟動項目,不會刷新pom,先手動刷新,再啟動項目,都要確保maven沒問題
-
Druid數(shù)據(jù)源的crud項目
-
準備dao層依賴文本
- jdbc
- mybatis
- mysql
- druid
- druid-start
- <!--數(shù)據(jù)庫--> <!--jdbc--> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jdbc</artifactId> </dependency><!--mybatis--> <dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.1.3</version> </dependency> <!--mysql--> <dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope> </dependency> <!--druid--> <dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.10</version> </dependency> <dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.1.9</version> </dependency> <!--log4j--> <dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version> </dependency>
-
druid-spring-boot-starter是可以不加的,作為一個可視化的后臺管理,可以通過配置文件的配置,或javaconfig方式的配置形式配置,二者只能選其一,
-
加了druid-spring-boot-starter可以用配置文件配置,不加就只能通過javaconfig配置方式配置
-
如果使用兩種方式配置,會優(yōu)先使用自定義配置的配置
-
確保成功進行一個簡單的測試
-
測試數(shù)據(jù)源
-
http://localhost:8080/druid/index.html
-
寫一個簡單的test
- @SpringBootTest class Demo2ApplicationTests {@AutowiredJdbcTemplate jdbcTemplate;@Testvoid contextLoads() {for (Map<String, Object> stringObjectMap : jdbcTemplate.queryForList("select * from dept")) {System.out.println(stringObjectMap);}} }
-
設置熱部署
- <!--devtools--> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope><optional>true</optional> </dependency><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><fork>true</fork><addResources>true</addResources></configuration></plugin></plugins>
-
application
- ### db config ### spring.datasource.type=com.alibaba.druid.pool.DruidDataSource spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver spring.datasource.url=jdbc:mysql://localhost:3306/db01?useUnicode=true&characterEncoding=utf8¤tSchema=public spring.datasource.username=root spring.datasource.password=123456#spring.datasource.druid.filters=stat,log4jserver.port=8001#初始化時建立物理連接的個數(shù) spring.datasource.druid.initial-size=5 #最小連接池數(shù)量 spring.datasource.druid.min-idle=5 #最大連接池數(shù)量 maxIdle已經(jīng)不再使用 spring.datasource.druid.max-active=20 #獲取連接時最大等待時間,單位毫秒 spring.datasource.druid.max-wait=60000#spring.datasource.druid.stat-view-servlet.login-username=admin #spring.datasource.druid.stat-view-servlet.login-password=admin### mybatis config ### mybatis.mapper-locations=classpath:mybatis/mapper/*.xml mybatis.type-aliases-package=com.haoyun.pojo.Dept
-
deptMapper
- <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.haoyun.dao.DeptDao"><insert id="insertDept" parameterType="com.haoyun.pojo.Dept">insert into dept ( dname, db_source)values (#{dname}, #{db_source});</insert><select id="selectAll" resultType="com.haoyun.pojo.Dept">select * from dept</select><select id="selectById" resultType="com.haoyun.pojo.Dept" parameterType="long">select * from dept where deptno=#{deptno}</select> </mapper>
-
DeptDao
- @Mapper @Repository public interface DeptDao {boolean insertDept(Dept dept);List<Dept> selectAll();Dept selectById(long deptno); }
-
DruidConfig
- package com.haoyun.config;import com.alibaba.druid.pool.DruidDataSource; import com.alibaba.druid.support.http.StatViewServlet; import com.alibaba.druid.support.http.WebStatFilter; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.boot.web.servlet.ServletRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;import javax.sql.DataSource;@Configuration public class DruidConfig {@Bean@ConfigurationProperties(prefix = "spring.datasource")public DataSource getDataSource() {return new DruidDataSource();}@Beanpublic ServletRegistrationBean druidStatViewServlet() {//ServletRegistrationBean提供類的進行注冊ServletRegistrationBean servletRegistrationBean =new ServletRegistrationBean(new StatViewServlet(), "/druid/*");//添加初始化參數(shù):initParams//白名單:servletRegistrationBean.addInitParameter("allow", "127.0.0.1");//IP黑名單(同時存在時,deny優(yōu)先于allow)//如果滿足deny,就提示:sorry,you are not permitted to view this pageservletRegistrationBean.addInitParameter("deny", "192.168.1.73");//登錄查看信息的賬號和密碼servletRegistrationBean.addInitParameter("loginUsername", "admin");servletRegistrationBean.addInitParameter("loginPassword", "123456");servletRegistrationBean.addInitParameter("resetEnable", "false");return servletRegistrationBean;}@Beanpublic FilterRegistrationBean druidStatFilter() {FilterRegistrationBean filterRegistrationBean =new FilterRegistrationBean(new WebStatFilter());//添加過濾規(guī)則filterRegistrationBean.addUrlPatterns("/*");//添加需要忽略的格式信息filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif," +"*.jpg,*.png, *.css,*.ico,/druid/*");return filterRegistrationBean;}}
-
DeptServiceImpl
- @Service public class DeptServiceImpl implements DeptService {@AutowiredDeptDao deptDao;@Overridepublic boolean insertDept(Dept dept) {return deptDao.insertDept(dept);}@Overridepublic List<Dept> selectAll() {return deptDao.selectAll();}@Overridepublic Dept selectById(long deptno) {return deptDao.selectById(deptno);} }
-
DeptController
- @RestController @RequestMapping("/dept") public class DeptController {@AutowiredDeptServiceImpl deptDao;@RequestMapping("/all")public List<Dept> all(){return deptDao.selectAll();}@PostMapping("/add")//由于是通過http rest方式交互,必須加上@RequestBody//必須使用post,consumer端通過postForObject傳輸?shù)?/span>public boolean add( @RequestBody Dept dept){return deptDao.insertDept(dept);}@RequestMapping("/get/{id}")private Dept get(@PathVariable long id){return deptDao.selectById(id);}}
-
因為加了@RequestBody,直接訪問服務端的add會報400錯誤,但是通過客戶端訪問是沒問題的
-
provider測試
- http://localhost:8001/dept/add?dname=%E6%B5%8B%E8%AF%95&db_source=db01 http://localhost:8080/consumer/add?dname=sadfa&db_source=db01
consumer
消費者不需要連接數(shù)據(jù)庫,
消費者不應該有Service層
使用RestFul風格請求,
主要流程:
- 導入maven
- web
- spring-cloud
- Configuration
- 注冊RestTemplate的bean
- controller
- 連接上provider就行
實現(xiàn):
-
pom
- <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-dependencies --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>Greenwich.SR3</version><type>pom</type><scope>runtime</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope><exclusions><exclusion><groupId>org.junit.vintage</groupId><artifactId>junit-vintage-engine</artifactId></exclusion></exclusions></dependency></dependencies>
-
spring-cloud-dependencies下載失敗,要加
- <type>pom</type><scope>runtime</scope>
-
config
- @Configuration public class ConfigBean {@Beanpublic RestTemplate getRestTemplate(){return new RestTemplate();} }
-
注冊bean
- @RestController @RequestMapping("/consumer") public class DeptConsumerController {@AutowiredRestTemplate restTemplate;private static final String REST_URL_PREFIX = "http://localhost:8001";@RequestMapping("/all")public List<Dept> all(){return restTemplate.getForObject(REST_URL_PREFIX+"/dept/all", List.class);}@RequestMapping("/add")public boolean add(Dept dept){System.out.println("============="+dept);return restTemplate.postForObject(REST_URL_PREFIX+"/dept/add",dept,Boolean.class);}@RequestMapping("/get/{id}")private Dept get(@PathVariable("id") long id){return restTemplate.getForObject(REST_URL_PREFIX+"/dept/get/"+id,Dept.class,id);}}
-
url一定要對上和respond要對上,要不然會報404,或500錯誤
-
設置端口為8080,一般用戶都要使用默認端口,不讓用戶多設置
Eureka服務注冊與發(fā)現(xiàn)
Eureka作為服務注冊與發(fā)現(xiàn),是C S架構的,client,Server
遵循AP原則
NetFlix的核心模塊,基于Rest服務,用于定位服務,以實現(xiàn)云端中間層服務發(fā)現(xiàn)和故障轉移,有了服務注冊與發(fā)現(xiàn),只需要使用服務的標識符,就可以訪問到服務,不需要修改服務調用的配置文件,類似于Dubbo的Zookeeper注冊中心
EurekaServer作為服務注冊功能的服務器
心跳機制,維護人員可以通過Eureka監(jiān)控系統(tǒng)中各個微服務是否正常運行,各個注冊的微服務定時給Eureka發(fā)送信號,如果Eureka長時沒收到信號就判定為這個微服務出問題,移除服務節(jié)點,默認周期為90秒
Eureka包含兩個組件:EurekaServer和EurekaClient
三個角色:
- EurekaServer
- EurekaProvider
- EurekaConsumer
EurekaServer
流程:
- 導入依賴
- 編寫配置文件
- 開啟功能@enable
- 配置類
實現(xiàn):
-
導入依賴
-
根據(jù)三種不同的角色導入不同的依賴
-
也可以直接創(chuàng)建項目的時候選
- <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency>
-
配置
- server.port=7001 eureka.instance.hostname=localhost #服務實例化名稱 eureka.client.register-with-eureka=false #是否向服務端口注冊自己 eureka.client.fetch-registry=false #表示自己為注冊中心 eureka.client.service-url.serviceUrl=http://${eureka.instance.hostname}:${server.port}/eureka/
-
設置serviceurl
-
源碼中需要傳遞一個map
-
通過源碼查找默認的serviceUrl是怎么寫的
-
滑倒上面有一個DefaultURl
-
默認端口號8761,加上prefix,/eureka加/
-
是默認的格式
-
所以更改serviceUrl就要以這個格式
-
配置啟動類
- @SpringBootApplication @EnableEurekaServer /*開啟EnableEurekaServer啟動類,可以接收服務端的注冊*/ public class SpringCloudEurekaApplication {public static void main(String[] args) {SpringApplication.run(SpringCloudEurekaApplication.class, args);}}
-
訪問
-
instances currently registered with Eureka
-
當前注冊實例
EurekaProvider
-
導入依賴:
-
三種依賴,一種帶server,一種client,一種什么都不帶的就是Provider的就是了
-
好像改版了,什么都不帶的maven不知道為什么加載不進來
-
就使用了client后綴的,spring-cloud-starter-eureka-client
- <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId><version>2.2.5.RELEASE</version> </dependency>
-
主要也就三個操作
- 導入依賴
- 配置文件
- 啟動類@EnableEurekaClient
- eureka.client.service-url.defaultZone=http://localhost:7001/eureka/ eureka.instance.instance-id=springCloud-provider-dept8001
- @SpringBootApplication @EnableEurekaClient public class Demo2Application {public static void main(String[] args) {SpringApplication.run(Demo2Application.class, args);}}
-
因為中間更改了DefaultZone,server在心跳時間內(nèi)沒收到這個provider的心跳信息,判定為失效,作為安全期間,實例沒有被消除,信息被保存了
-
這是Eureka的自我保護機制,沒有接收到微服務的心跳,會保存微服務的信息,微服務突然失效是十分危險的,因為i微服務本身是健康的,此時不應該注銷這個微服務,Eureka通過自我保護機制,當短時間丟失過多節(jié)點,可能發(fā)生了網(wǎng)絡分區(qū)故障,這個節(jié)點就會進入自我保護機制,自我保護機制會保存注冊表中的信息,不再刪除注冊表中的數(shù)據(jù),網(wǎng)絡故障結束后會自動推出自我保護機制
-
寧可保留錯誤的服務注冊信息,也不銷毀任何可能健康的服務實例
-
使用eureka.server.enable-self-preservation = false 可以禁用自我保護機制
-
這還不是真正的自我保護機制
視頻還演示了通過獲取Eureka的信息
總結
以上是生活随笔為你收集整理的SpringCloud 单Eureka简单例子consumer-provider的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ueditor编辑器复制粘贴图片上传
- 下一篇: 电信宽带,改桥接,设置端口转发,TCP,