SpringCloud(一)搭建微服務框架

談談架構演變

單體應用:ALL IN ONE

在之前我們,開發一個應用時,只創建一個項目,把所有的頁面、代碼都放着裏面,把這個項目打成war包部署在tomcat中。
優點:

  • 開發測試簡便:由於是一個應用,不存在多個應用之間的互聯互調
  • 部署簡便:打一個war包部署在tomcat中,不會給運維帶來太多工作挑戰
  • 水平拓展簡便:當應用負載能力差時,只需將相同的這一個應用拷貝到很多個服務器上面,多個服務器同時跑這個項目,通過負載均衡機制提高併發能力

缺點:

  • 牽一髮動全身:只要是修改代碼,那麼就得重新部署項目
  • 隨着現代軟件應用發展,任何一個應用都可能是一個大型應用,不可能ALL IN ONE,維護和分工困難

微服務

爲了解決上面所說的問題,覺定把項目細化,分出多個模塊,微化服務。每一個服務都是一個可替換可獨立升級的軟件單元,每個軟件單元通過http互聯互調就形成了一個輕量級應用網。這些服務可以通過http或者RPC的方式進行互通。

  • 節省了調用資源。
  • 每個功能元素的服務都是一個可替換的、可獨立升級的軟件代碼。真正的高內聚、低耦合。

而在微服務階段,面臨的問題如:服務的部署、連橋,服務間調度、負載均衡、服務熔斷、消息隊列等都需要去了解學習。路還很長加油!!!
springboot可以快速的構建一個軟件單元,也就是快速的構建一個獨立的服務。而大型分佈式網絡服務的調用,是有springcloud來完成,實現分佈式

SpringCloud

是一套目前完整的微服務框架,它是是一系列框架的有序集合。它只是將目前各家公司開發的比較成熟、經得起實際考驗的服務框架組合起來,通過SpringBoot風格進行再封裝屏蔽掉了複雜的配置和實現原理,最終給開發者留出了一套簡單易懂、易部署和易維護的分佈式系統開發工具包。它利用Spring Boot的開發便利性巧妙地簡化了分佈式系統基礎設施的開發,如服務發現註冊、配置中心、消息總線、負載均衡、斷路器、數據監控等,都可以用SpringBoot的開發風格做到一鍵啓動和部署。

第一個SpringCloud程序

案例的環境依賴

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.baidu</groupId>
    <artifactId>cloud-test</artifactId>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>user-service</module>
        <module>consumer-demo</module>
        <module>eureka-sever</module>
    </modules>
    <packaging>pom</packaging>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.4.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <spring-cloud.version>Finchley.SR1</spring-cloud.version>
        <mapper.starter.version>2.0.3</mapper.starter.version>
        <mysql.version>5.1.32</mysql.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <!-- springCloud -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!--通用Mapper啓動器-->
            <dependency>
                <groupId>tk.mybatis</groupId>
                <artifactId>mapper-spring-boot-starter</artifactId>
                <version>${mapper.starter.version}</version>
            </dependency>
            <!-- mysqL驅動-->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>${mysql.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

user-service子服務

作爲服務的提供方。
在這裏插入圖片描述
application.yml配置

server:
  port: 8081
#控制日誌級別
logging:
  level:
    com.baidu: debug

# 數據庫連接信息
spring:
  application:
    name: user-service
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/spring_study_db?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
    username: root
    password: admin

#配置mybatis的信息
mybatis:
  #pojo別名掃描
  type-aliases-package: com.baidu.user.pojo
  #加載mybatis映射文件,使用通用Mapper這個就不用了
  #mapper-locations: classpath:mapper/*mapper.xml

controller代碼:

@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;

    @GetMapping("/findById/{id}")
    public User findById(@PathVariable("id")Integer id){
        return userService.findById(id);
    }

    @GetMapping("/findAll")
    public List<User> findAll(){
        return userService.findAll();
    }

}

consemer-demo子服務

作爲服務的消費方。

在這裏插入圖片描述
application.yml配置

server:
  port: 8082

spring:
  application:
    name: consumer-server

controller代碼:

@RestController
@Reques tMapp ing ("Consumer")
public class Consume rController [
	@Autowired
	private RestTemplate restTemplate;
	@GetMapping("{id}" )
	public User queryById (@PathVariable("id") Long id){
		String url = "http: //Localhost: 8081/user/findById/" + id;
		User user = restTemplate.getForobject(url, User.class) ;
		return user;
	}
}

這裏我們通過consemer-demo子服務去調用了user-service子服務。

思考上面代碼問題

簡單回顧一下寫了什麼,有沒有問題?
user-service:對外提供了查詢用戶的接口
consumer:通過RestTemplate訪問 http: //Localhost: 8081/user/findById/{id} 接口,查詢用戶數據

  • 存在問題:
●在consumer中, 我們把url地址硬編碼到了代碼中,不方便後期維護
●consumer需要記憶user-service的地址,如果出現變更,可能得不到通知,地址將失效
●consumer不清楚user-service的狀態, 服務宕機也不知道
●user-service只有1臺服務, 不具備高可用性
●即便user-service形成集羣, consumer還需自己實現負載均衡
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章