【微服務架構】springcloud微服務架構搭建
1 Star2 Stars3 Stars4 Stars5 Stars 給文章打分!
Loading...

要會用,首先要了解。圖懶得畫,借鑑網上大牛的圖吧,springcloud組建架構如圖:

微服務架構的應用場景:

1、系統拆分,多個子系統

2、每個子系統可部署多個應用,應用之間負載均衡實現

3、需要一個服務註冊中心,所有的服務都在註冊中心註冊,負載均衡也是通過在註冊中心註冊的服務來使用一定策略來實現。

4、所有的客戶端都通過同一個閘道器地址訪問後臺的服務,通過路由配置,閘道器來判斷一個URL請求由哪個服務處理。請求轉發到服務上的時候也使用負載均衡。

5、服務之間有時候也需要相互訪問。例如有一個使用者模組,其他服務在處理一些業務的時候,要獲取使用者服務的使用者資料。

6、需要一個斷路器,及時處理服務呼叫時的超時和錯誤,防止由於其中一個服務的問題而導致整體系統的癱瘓。

7、還需要一個監控功能,監控每個服務呼叫花費的時間等。

Spring Cloud的優勢

  • 產出於spring大家族,spring在企業級開發框架中無人能敵,來頭很大,可以保證後續的更新、完善。比如dubbo現在就差不多死了
  • 有spring Boot 這個獨立干將可以省很多事,大大小小的活spring boot都搞的挺不錯。
  • 作為一個微服務治理的大傢伙,考慮的很全面,幾乎服務治理的方方面面都考慮到了,方便開發開箱即用。
  • Spring Cloud 活躍度很高,教程很豐富,遇到問題很容易找到解決方案
  • 輕輕鬆鬆幾行程式碼就完成了熔斷、均衡負責、服務中心的各種平臺功能

廢話少說,看程式碼:

專案架構:

一、discovery服務註冊發現

①、pom.xml

<?xml version="1.0"?>
<project
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.gt</groupId>
<artifactId>popuserver</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>discovery</artifactId>
<name>discovery</name>
<url>http://www.popumusic</url>
<properties>
<start-class>com.wisely.discovery.DiscoveryApplication</start-class>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

②、DiscoveryApplication

package com.wisely.discovery;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer //1
public class DiscoveryApplication {
public static void main(String[] args) {
SpringApplication.run(DiscoveryApplication.class, args);
}
}

③、application.yml

server:
port: 8761
endpoints:
shutdown:
enabled: true
sensitive: false
eureka:
instance:
prefer-ip-address: true  #啟用IP方式
ip-address: 127.0.0.1 
client:
register-with-eureka: false #指向其他註冊中心地址
fetch-registry: false
service-url:
defualtZone: http://127.0.0.1:8762/eureka/

二、monitor監控服務

①、pom.xml

<?xml version="1.0"?>
<project
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.gt</groupId>
<artifactId>popuserver</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<groupId>com.poputar</groupId>
<artifactId>popumonitor</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>popumonitor</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter</artifactId>
<version>1.1.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
<version>1.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-turbine</artifactId>
<version>1.1.7.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<configuration>
<imageName>${project.name}:${project.version}</imageName>
<dockerDirectory>${project.basedir}/src/main/docker</dockerDirectory>
<skipDockerBuild>false</skipDockerBuild>
<resources>
<resource>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
</configuration>
</plugin>
</plugins>
</build>
</project>

②、PopumonitorApplication

package com.poputar;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;
import org.springframework.cloud.netflix.turbine.EnableTurbine;
/**
* 監控服務
*
*/
@SpringBootApplication
@EnableEurekaClient
@EnableHystrixDashboard
@EnableTurbine
public class PopumonitorApplication 
{
public static void main( String[] args )
{
SpringApplication.run(PopumonitorApplication.class, args);
}
}

③、application.yml

server:
port: 8989

④、bootstrap.yml

spring:
application:
name: monitor
eureka:
instance:
nonSecurePort: ${server.port:8989}
client:
serviceUrl:
defaultZone: http://${eureka.host:localhost}:${eureka.port:8761}/eureka/

三、配置服務

①、pom.xml

<?xml version="1.0"?>
<project
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.gt</groupId>
<artifactId>popuserver</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<groupId>com.poputar</groupId>
<artifactId>popuconfig</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>popuconfig</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter</artifactId>
<version>1.1.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
<version>1.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
<version>1.1.7.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<configuration>
<imageName>${project.name}:${project.version}</imageName>
<dockerDirectory>${project.basedir}/src/main/docker</dockerDirectory>
<skipDockerBuild>false</skipDockerBuild>
<resources>
<resource>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
</configuration>
</plugin>
</plugins>
</build>
</project>

②、PopuconfigApplication

package org.popuconfig;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
/**
* 配置服務
*
*/
@SpringBootApplication
@EnableConfigServer
@EnableEurekaClient
public class PopuconfigApplication
{
public static void main( String[] args )
{
SpringApplication.run(PopuconfigApplication.class, args);
}
}

③、application.yml 配置檔案放本地,讀者可以自己研究下放在git服務上

spring:
cloud:
config:
server:
native:
search-locations: classpath:/config
server:
port: 8762

④、bootstrap.yml

spring:
application:
name: config #1
profiles:
active: native #2 
eureka:
instance:
non-secure-port: ${server.port:8762} #3
metadata-map:
instanceId: ${spring.application.name}
client:
service-url:
defaultZone: http://${eureka.host:localhost}:${eureka.port:8761}/eureka/ #5

⑤、src/main/resources/config下放應用所需的配置檔案,命名方式跟appname相同,切記此處的命名是有規範的

四、使用者服務

①、pom.xml 需要引入外部jar包時,我已做註釋,如下:

<?xml version="1.0"?>
<project
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.gt</groupId>
<artifactId>popuserver</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>popuman</artifactId>
<name>popuman</name>
<url>http://www.popumusic</url>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>aliyun-java-sdk-dysmsapit</groupId>
<artifactId>aliyun-java-sdk-dysmsapi</artifactId>
<version>1.0.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/aliyun-java-sdk-dysmsapi-1.0.0.jar</systemPath>
</dependency>
<dependency>
<groupId>aliyun-java-sdk-core</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<version>3.3.1</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/aliyun-java-sdk-core-3.3.1.jar</systemPath>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
<!-- 將外部包打入jar docker部署時需要開啟,否則報錯,找不到jar -->
<!-- <resources>
<resource>
<directory>lib</directory>
<targetPath>BOOT-INF/lib/</targetPath>
<includes>
<include>**/*.jar</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<targetPath>BOOT-INF/classes/</targetPath>
</resource>
</resources> -->
</build>
</project>

②、PopumanApplication 增加了國際化配置

package com.gt;
import javax.validation.Validator;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
@SpringBootApplication
@EnableEurekaClient
public class PopumanApplication {
public static void main(String[] args) {
SpringApplication.run(PopumanApplication.class, args);
}
public ResourceBundleMessageSource getMessageSource() throws Exception {  
ResourceBundleMessageSource rbms = new ResourceBundleMessageSource();  
rbms.setDefaultEncoding("UTF-8");  
rbms.setBasenames("i18n/ValidationMessages");  
return rbms;  
}  
@Bean  
public Validator getValidator() throws Exception {  
LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();  
validator.setValidationMessageSource(getMessageSource());  
return validator;  
}
}

③、LocaleConfig 攔截器

package com.gt;
import java.util.Locale;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;
@Configuration
@EnableAutoConfiguration
@ComponentScan	
public class LocaleConfig extends WebMvcConfigurerAdapter {
@Bean
public LocaleResolver localeResolver() {
SessionLocaleResolver slr = new SessionLocaleResolver();
// 預設語言
slr.setDefaultLocale(Locale.US);
return slr;
}
@Bean
public LocaleChangeInterceptor localeChangeInterceptor() {
LocaleChangeInterceptor lci = new LocaleChangeInterceptor();
// 引數名
lci.setParamName("lang");
return lci;
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(localeChangeInterceptor());
}
}

④、MessageManager 讀取國際化檔案內容

package com.gt;
import java.util.Locale;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Component;
@Component  
public class MessageManager {  
private static MessageSource messageSource;   
public static String getMsg(String key) {  
Locale locale = LocaleContextHolder.getLocale();  
return messageSource.getMessage(key, null, locale);  
}  
public static String getMsg(String key, String... arg) {  
Locale locale = LocaleContextHolder.getLocale();  
Object[] args = new Object[arg.length];  
for (int i = 0; i < arg.length; i  ) {  
args[i] = arg[i];  
}  
return messageSource.getMessage(key, args, locale);  
}  
@Autowired(required = true)  
public void setMessageSource(MessageSource messageSource) {  
MessageManager.messageSource = messageSource;  
}  
}

⑤、application.yml

debug: true
server:
port: 8781

⑥、bootstrap.yml docker環境下部署時需要指定ip,否則找不到配置服務,讀取不了配置中心的相關配置

spring:
application:
name: popuman
cloud:
config:
enabled: true
discovery:  #配置服務發現,獲取配置資訊 配置檔案命名要按照springcloud config配置檔案命名規則命名
enabled: true
service-id: config
eureka:
instance:
appname: popuman 
client:
service-url:
defaultZone: http://${eureka.host:localhost}:${eureka.port:8761}/eureka/       
#docker環境下需指定ip才能訪問   
#eureka:
#  instance:
#    appname: popuman       
#    prefer-ip-address: true  #啟用IP方式
#    ip-address: 192.168.*.**
#  client:
#   service-url:
#      defaultZone: http://192.168.*.**:8761/eureka/  

⑦、logback.xml 日誌分級別輸出到檔案,dubug,error級別日誌輸出到各自的日誌檔案

<configuration>    
<!-- %m輸出的資訊,%p日誌級別,%t執行緒名,%d日期,%c類的全名,,,, -->    
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">    
<encoder>    
<pattern>%d %p (%file:%line\)- %m%n</pattern>  
<charset>UTF-8</charset>   
</encoder>    
</appender>    
<appender name="popuman"    
class="ch.qos.logback.core.rolling.RollingFileAppender">      
<File>/Users/david/Documents/Poputar/logs/popuman.log</File>    
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">    
<fileNamePattern>/Users/david/Documents/Poputar/logs/popuman.%d.%i</fileNamePattern>    
<timeBasedFileNamingAndTriggeringPolicy  class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">    
<!-- or whenever the file size reaches 64 MB -->    
<maxFileSize>64 MB</maxFileSize>    
</timeBasedFileNamingAndTriggeringPolicy>    
</rollingPolicy>    
<encoder>    
<pattern>    
%d %p (%file:%line\)- %m%n  
</pattern>    
<charset>UTF-8</charset> <!-- 此處設定字符集 -->   
</encoder> 
<filter class="ch.qos.logback.classic.filter.LevelFilter"> <!-- 過濾錯誤日誌 -->
<level>ERROR</level>  
<onMatch>DENY</onMatch>  
<onMismatch>ACCEPT</onMismatch>  
</filter>   
</appender>    
<appender name="popuman_err"    
class="ch.qos.logback.core.rolling.RollingFileAppender">    
<File>/Users/david/Documents/Poputar/logs/popuman_err.log</File>    
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">    
<fileNamePattern>/Users/david/Documents/Poputar/logs/popuman_err.%d.%i</fileNamePattern>    
<timeBasedFileNamingAndTriggeringPolicy  class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">    
<!-- or whenever the file size reaches 64 MB -->    
<maxFileSize>64 MB</maxFileSize>    
</timeBasedFileNamingAndTriggeringPolicy>    
</rollingPolicy>    
<encoder>    
<pattern>    
%d %p (%file:%line\)- %m%n  
</pattern>    
<charset>UTF-8</charset> <!-- 此處設定字符集 -->   
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter"><!-- 只列印錯誤日誌 -->
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>     
</appender>    
<root level="info">    
<appender-ref ref="STDOUT" />    
</root>
<!-- 輸出日誌 -->
<logger name="com.gt" level="DEBUG">    
<appender-ref ref="popuman" />    
<appender-ref ref="popuman_err" />    
</logger>    
</configuration>

五、popumusic專案程式碼就不貼了,同popuman專案類似。

部署到docker時,切記埠對映好,否則調不通。

六、應用之間服務的呼叫是通過springcloud的FeignClient呼叫,這種呼叫方式同樣也是基於http協議,好處是不用我們再去封裝httpclient手寫post,get請求,通過呼叫方法的方式就可以呼叫其他服務介面

本架構採用springboot推薦的JPA方式來處理資料層,快取採用redis,如果您要問,redis掛掉怎麼辦?那就要考慮redis的分散式,主從等,這裡不做贅述。

spriingcloud是近兩年新興的微服務技術,目前我也是在學習中,如有覺得我寫的有不對的地方,還請批評指正,共同交流,學習一門新技術是枯燥的,難免走很多彎路,但是當你突破難關時,那樣的輕鬆是何等暢快!在這裡也感謝CSDN上大牛的技術文章分享,有分享才會有進步。希望本文對學習springcloud的同學有所幫助。

推薦幾篇springcloud總結比較全的部落格,也是本文專案搭建過程借鑑的技術文章

方誌鵬大牛部落格地址:http://blog.csdn.net/forezp/article/category/6830968/1

司青部落格:http://blog.csdn.net/neosmith/article/details/52449921

http://blog.csdn.net/f1576813783/article/details/76805195

方誌鵬http://blog.csdn.net/forezp/article/category/68

相關文章

程式語言 最新文章