SpringCloud
服务发现Euraka
1、创建空父maven项目,pom文件内容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| <?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>
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.2.0.RELEASE</version> <relativePath/> </parent>
<groupId>com.syl</groupId> <artifactId>springcloud01</artifactId> <version>1.0-SNAPSHOT</version> <packaging>pom</packaging> <properties> <java.version>1.8</java.version> </properties>
<dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Greenwich.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
|
2、创建springboot项目,选择spring Cloud Discovery –> Eureka Server,pom文件内容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
| <?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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>com.syl</groupId> <artifactId>springcloud01</artifactId> <version>1.0-SNAPSHOT</version> <relativePath/> </parent> <groupId>com.syl</groupId> <artifactId>euraka-server</artifactId> <version>0.0.1-SNAPSHOT</version> <name>euraka-server</name> <description>Demo project for Spring Boot</description>
<properties> <java.version>1.8</java.version> <spring-cloud.version>Hoxton.RC1</spring-cloud.version> </properties>
<dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </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>
<dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
<repositories> <repository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/milestone</url> </repository> </repositories>
</project>
|
3、application.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| server: port: 8888
spring: application: name: eureka-server01
eureka: client: register-with-eureka: false fetch-registry: false service-url: defaultZone: http://localhost:${server.port}/eureka
|
4、启动类
1 2 3 4 5 6 7 8
| @SpringBootApplication @EnableEurekaServer public class AppStart {
public static void main(String[] args) { SpringApplication.run(AppStart.class, args); } }
|
浏览器地址栏输入 http://localhost:8888/测试
5、服务提供方,以往的service层和dao层,使用jpa
pom
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
| <?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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>com.syl</groupId> <artifactId>springcloud01</artifactId> <version>1.0-SNAPSHOT</version> </parent> <groupId>com.syl</groupId> <artifactId>user-provide01</artifactId> <version>0.0.1-SNAPSHOT</version> <name>user-provide01</name> <description>Demo project for Spring Boot</description>
<properties> <java.version>1.8</java.version> <spring-cloud.version>Hoxton.RC1</spring-cloud.version> </properties>
<dependencies>
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </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>
<dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
<repositories> <repository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/milestone</url> </repository> </repositories>
</project>
|
application.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| server: port: 10010
spring: application: name: userprovider datasource: url: jdbc:mysql://localhost:3306/tempdata?serverTimezone=UTC username: root password: root001 driver-class-name: com.mysql.cj.jdbc.Driver jpa: hibernate: ddl-auto: update show-sql: true
|
User.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
| package com.syl.userprovide01.entity;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id;
@Entity
@JsonIgnoreProperties(value = { "hibernateLazyInitializer"}) public class User { @Id @GeneratedValue private Integer id;
@Column(name="name",nullable = true,length = 20) private String name;
@Column(name = "age",nullable = true,length = 4) private Integer age;
public User() { }
public User(String name, Integer age) { this.name = name; this.age = age; }
public Integer getId() { return id; }
public void setId(Integer id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public Integer getAge() { return age; }
public void setAge(Integer age) { this.age = age; } }
|
UserController.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
| package com.syl.userprovide01.controller;
import com.syl.userprovide01.entity.User; import com.syl.userprovide01.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*;
import java.util.HashMap; import java.util.List; import java.util.Map;
@RestController @RequestMapping("/user") public class UserController {
@Autowired UserService userService;
@GetMapping("/getall") public Map<String,Object> getUsers() { Map<String,Object> map=new HashMap<>(); List<User> list = userService.getUserList(); map.put("list", list); String ProviderVersion="User-Provide01"; map.put("ProviderVersion", ProviderVersion); return map; }
@PostMapping("/save") public String createUser(@RequestBody User user) { try { userService.createUser(user); } catch (Exception e) { e.printStackTrace(); return "error"; } return "success"; } @GetMapping("/get/{id}") public User findUser(@PathVariable("id") Integer id) { User user =null; try { user= userService.getUser(id); System.out.println("返回user:"+user); } catch (Exception e) {
System.out.println("数据查询失败:"); return user; } return user; }
@PutMapping("/update/{id}") public String editUser(@RequestBody User user, @PathVariable("id") Integer id) { try { userService.updateUser(user.getId(), user); } catch (Exception e) { e.printStackTrace(); return "error"; } return "success"; }
@DeleteMapping("/delete/{id}") public String deleteUser(@PathVariable("id") Integer id) { try { userService.deleteUser(id); } catch (Exception e) { e.printStackTrace(); return "error"; } return "success";
}
@GetMapping("/getversion") public String getVersion() {
return "User-Provide01"; } }
|
UserService
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| package com.syl.userprovide01.service;
import com.syl.userprovide01.entity.User;
import java.util.List;
public interface UserService { public List<User> getUserList(); public void createUser(User user); public User getUser(Integer id); public void updateUser(Integer id,User user); public void deleteUser(Integer id);
}
|
UserServiceImpl.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| package com.syl.userprovide01.service.impl;
import com.syl.userprovide01.dao.UserRepository; import com.syl.userprovide01.entity.User; import com.syl.userprovide01.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service;
import java.util.List;
@Service public class UserServiceImpl implements UserService {
@Autowired UserRepository userRepository;
@Override public List<User> getUserList() { return userRepository.findAll(); }
@Override public void createUser(User user) { userRepository.save(user); }
@Override public User getUser(Integer id) { return userRepository.getOne(id); }
@Override public void updateUser(Integer id, User user) { user.setId(id); userRepository.saveAndFlush(user); }
@Override public void deleteUser(Integer id) { userRepository.deleteById(id); } }
|
UserRepository.java
1 2 3 4 5 6 7 8 9 10 11 12
| package com.syl.userprovide01.dao;
import com.syl.userprovide01.entity.User; import org.springframework.data.jpa.repository.JpaRepository;
public interface UserRepository extends JpaRepository<User,Integer> { }
|
启动类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| package com.syl.userprovide01;
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@SpringBootApplication @EnableDiscoveryClient public class UserProvide01Application {
public static void main(String[] args) { SpringApplication.run(UserProvide01Application.class, args); }
}
|
6、消费方,以往的controller层
pom.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
| <?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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion>
<parent> <groupId>com.syl</groupId> <artifactId>springcloud01</artifactId> <version>1.0-SNAPSHOT</version> </parent> <groupId>com.syl</groupId> <artifactId>user-web</artifactId> <version>0.0.1-SNAPSHOT</version> <name>user-web</name> <description>Demo project for Spring Boot</description>
<properties> <java.version>1.8</java.version> <spring-cloud.version>Hoxton.RC1</spring-cloud.version> </properties>
<dependencies>
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.webjars</groupId> <artifactId>bootstrap</artifactId> <version>4.2.1</version> </dependency>
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </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>
<dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
<repositories> <repository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/milestone</url> </repository> </repositories>
</project>
|
application.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| server: port: 10086 spring: thymeleaf: cache: false
application: name: userweb1 eureka: client: service-url: defaultZone: http://localhost:8888/eureka/,http://localhost:8889/eureka/ instance: prefer-ip-address: true
|
UserController.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
| package com.syl.userweb.controller;
import com.syl.userweb.entity.User; import com.syl.userweb.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping;
import java.util.List; import java.util.Map;
@Controller public class UserController {
@Autowired UserService userService;
@GetMapping("/") public String getUserList(Model model){ Map map = userService.getUserMap(); List<User> list=(List<User>) map.get("list"); model.addAttribute("page", list); model.addAttribute("ProviderVersion", map.get("ProviderVersion"));
return "user/list"; }
@RequestMapping("/toAdd") public String toadd(User user){ return "user/userAdd"; } @PostMapping("/add") public String createUser(User user) { userService.createUser(user); return "redirect:/"; } @RequestMapping("/toEdit/{id}") public String toEdit(Model model,@PathVariable("id")Integer id){ User user = userService.getUser(id); model.addAttribute("user",user); return "user/userEdit"; }
@RequestMapping("/edit") public String edit(User user){ userService.updateUser(user.getId(), user); return "redirect:/"; } @GetMapping("/delete/{id}") public String deleteUser(@PathVariable("id") Integer id) { userService.deleteUser(id); return "redirect:/";
}
}
|
User.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| package com.syl.userweb.entity;
public class User {
private Integer id;
private String name;
private Integer age;
public User() { }
public User(Integer id, String name, Integer age) { this.id = id; this.name = name; this.age = age; }
public Integer getId() { return id; }
public void setId(Integer id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public Integer getAge() { return age; }
public void setAge(Integer age) { this.age = age; } }
|
UserService.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| package com.syl.userweb.service;
import com.syl.userweb.entity.User;
import java.util.Map;
public interface UserService { public Map getUserMap(); public void createUser(User user); public User getUser(Integer id); public void updateUser(Integer id,User user); public void deleteUser(Integer id);
}
|
UserServiceImpl.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
| package com.syl.userweb.service.impl;
import com.netflix.appinfo.InstanceInfo;
import com.syl.userweb.entity.User; import com.syl.userweb.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient; import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate;
import java.lang.reflect.Field; import java.util.List; import java.util.Map;
@Service public class UserServiceImpl implements UserService { @Autowired RestTemplate restTemplate;
@Autowired DiscoveryClient discoveryClient;
public String getServerUrl() {
List<ServiceInstance> userprovide = discoveryClient.getInstances("USERPROVIDER"); System.out.println(userprovide); ServiceInstance inst = userprovide.get(0);
String instanceId = inst.getInstanceId();
System.out.println(instanceId);
String ip = inst.getHost(); int port = inst.getPort(); String url="http://"+ip+":"+port+"/user"; System.out.println(url); return url;
}
@Override public Map getUserMap() { Map map = restTemplate.getForObject(getServerUrl()+"/getall", Map.class); System.out.println("come here");
return map; }
@Override public void createUser(User user) { restTemplate.postForObject(getServerUrl() + "/save", user, String.class); }
@Override public User getUser(Integer id) { return restTemplate.getForObject(getServerUrl() + "/get/" + id, User.class); }
@Override public void updateUser(Integer id, User user) { restTemplate.put(getServerUrl() + "/update/" + id, user); }
@Override public void deleteUser(Integer id) { restTemplate.delete(getServerUrl() + "/delete/" + id); } }
|
resources/templates/user/myfragment.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8" > <title>Title</title> </head> <body> <h1 th:fragment="head1" align="center">用户管理系统</h1> <h1 th:fragment="foot1"> © 1999-2018 Offcn.All Rights Reserved </h1>
</body> </html>
|
resources/templates/user/list.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| <!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"/> <title>userList</title> <link rel='stylesheet' th:href="@{/webjars/bootstrap/4.2.1/css/bootstrap.min.css}" href='webjars/bootstrap/4.2.1/css/bootstrap.min.css'> </head> <body class="container"> <div th:insert="~{user/myfragment :: head1}"></div> <br/> <h1><em th:text="${ProviderVersion}">服务提供方信息</em></h1> <br/><br/> <div class="with:80%"> <div class="form-group"> <div class="col-sm-2 control-label"> <a href="toAdd" th:href="@{toAdd}" class="btn btn-info">add</a> </div> </div> <table class="table table-hover"> <thead> <tr> <th>#</th> <th>Name</th> <th>Age</th> <th>Edit</th> <th>Delete</th> </tr> </thead> <tbody> <tr th:each="user : ${page}"> <th scope="row" th:text="${user.id}">1</th> <td th:text="${user.name}">neo</td> <td th:text="${user.age}">6</td> <td><a th:href="@{'toEdit/'+${user.id}}">edit</a></td> <td><a th:href="@{'delete/'+${user.id}}">delete</a></td> </tr> </tbody>
</table>
</div> <div th:include="~{user/myfragment :: foot1}"></div> </body> </html>
|
resources/templates/user/userAdd.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| <!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"/> <title>user</title> <link rel='stylesheet' th:href="@{/webjars/bootstrap/4.2.1/css/bootstrap.min.css}" href='webjars/bootstrap/4.2.1/css/bootstrap.min.css'> </head> <body class="container"> <div th:insert="~{user/myfragment :: head1}"></div> <br/> <h1>添加用户</h1> <br/><br/> <div class="with:80%"> <form class="form-horizontal" th:action="@{add}" method="post"> <div class="form-group"> <label for="name" class="col-sm-2 control-label">name</label> <div class="col-sm-10"> <input type="text" class="form-control" name="name" id="name" placeholder="name"/> </div> </div>
<div class="form-group"> <label for="age" class="col-sm-2 control-label">age</label> <div class="col-sm-10"> <input type="text" class="form-control" name="age" id="age" placeholder="age"/> </div> </div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <input type="submit" value="Submit" class="btn btn-info" /> <input type="reset" value="Reset" class="btn btn-info" /> </div>
</div> </form> </div> <div th:include="~{user/myfragment :: foot1}"></div> </body> </html>
|
resources/templates/user/userEdit.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| <!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"/> <title>user</title> <link rel='stylesheet' th:href="@{/webjars/bootstrap/4.2.1/css/bootstrap.min.css}" href='webjars/bootstrap/4.2.1/css/bootstrap.min.css'> </head> <body class="container"> <div th:insert="~{user/myfragment :: head1}"></div> <br/> <h1>修改用户</h1> <br/><br/> <div class="with:80%"> <form class="form-horizontal" th:action="@{/edit}" th:object="${user}" method="post"> <input type="hidden" name="id" th:value="*{id}" /> <div class="form-group"> <label for="name" class="col-sm-2 control-label">name</label> <div class="col-sm-10"> <input type="text" class="form-control" name="name" id="name" th:value="*{name}" placeholder="name"/> </div> </div>
<div class="form-group"> <label for="age" class="col-sm-2 control-label">age</label> <div class="col-sm-10"> <input type="text" class="form-control" name="age" id="age" th:value="*{age}" placeholder="age"/> </div> </div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <input type="submit" value="Submit" class="btn btn-info" /> <a href="/" th:href="@{/}" class="btn btn-info">Back</a> </div>
</div> </form> </div> <div th:include="~{user/myfragment :: foot1}"></div> </body> </html>
|
启动类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| package com.syl.userweb;
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; import org.springframework.context.annotation.Bean; import org.springframework.http.client.ClientHttpRequestFactory; import org.springframework.web.client.RestTemplate;
@SpringBootApplication @EnableDiscoveryClient public class UserWebApplication {
public static void main(String[] args) { SpringApplication.run(UserWebApplication.class, args); } @Bean public RestTemplate restTemplate(){ return new RestTemplate(); } }
|
7、注意事项
报错说serviceimpl中的restTemplate无法装载
在启动类中加入:
1 2 3 4
| @Bean public RestTemplate restTemplate(){ return new RestTemplate(); }
|
从消费方访问提供方时获取host时获取的是主机名不是ip的解决
application.yml中添加prefer-ip-address:true,优先使用ip注册服务
1 2 3 4 5 6
| eureka: client: service-url: defaultZone: http://localhost:8888/eureka/,http://localhost:8889/eureka/ instance: prefer-ip-address: true
|
Eureka高可用
1、复制EurakaServer01改名为02并修改配置文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| server: port: 8889
spring: application: name: eureka-server01
eureka: client: register-with-eureka: false fetch-registry: false service-url: defaultZone: http://localhost:8888/eureka
|
2、修改EurakaServer01的配置文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| server: port: 8888
spring: application: name: eureka-server01
eureka: client: register-with-eureka: false fetch-registry: false service-url: defaultZone: http://localhost:8889/eureka
|
3、修改提供方的配置文件为
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| server: port: 10010
spring: application: name: userprovider datasource: url: jdbc:mysql://localhost:3306/tempdata?serverTimezone=UTC username: root password: root001 driver-class-name: com.mysql.cj.jdbc.Driver jpa: hibernate: ddl-auto: update show-sql: true
eureka: client: service-url: defaultZone: http://localhost:8888/eureka/,http://localhost:8889/eureka/ instance: prefer-ip-address: true
|
4、修改消费方配置文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| server: port: 10086 spring: thymeleaf: cache: false
application: name: userweb1 eureka: client: service-url: defaultZone: http://localhost:8888/eureka/,http://localhost:8889/eureka/ instance: prefer-ip-address: true
|
服务调用组件
1、 服务调用基于LoadBalancerClient
1 2 3 4 5
| server: port: 8002 spring: application: name: userprovider
|
1 2 3 4 5 6 7
| server: port: 10087 spring: thymeleaf: cache: false application: name: userweb2
|
- 修改消费方的UserServiceImpl.java中的getUrl()方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| public class UserServiceImpl implements UserService {
@Autowired RestTemplate restTemplate; @Autowired LoadBalancerClient loadBalancerClient;
public String getServerUrl() { ServiceInstance inst = loadBalancerClient.choose("USERPROVIDER"); String ip = inst.getHost(); int port = inst.getPort(); String url="http://"+ip+":"+port+"/user"; return url; } }
|
2、服务调用基于Ribbon
1 2 3 4 5
| <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-ribbon</artifactId> </dependency>
|
1 2 3 4 5 6 7 8 9 10
| server: port: 10088 spring: thymeleaf: cache: false main: allow-bean-definition-overriding: true application: name: userweb
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| package com.syl.userweb; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.context.annotation.Bean; import org.springframework.web.client.RestTemplate;
@SpringBootApplication @EnableDiscoveryClient public class UserWeb03Application {
@Bean @LoadBalanced public RestTemplate restTemplate(){ return new RestTemplate(); } public static void main(String[] args) { SpringApplication.run(UserWeb03Application.class, args); } }
|
1 2 3 4 5
| @Autowired RestTemplate restTemplate;
String url="http://USERPROVIDER";
|
# com.netflix.loadbalancer.RandomRule #配置规则 随机
# com.netflix.loadbalancer.RoundRobinRule #配置规则 轮询
# com.netflix.loadbalancer.RetryRule #配置规则 重试
# com.netflix.loadbalancer.WeightedResponseTimeRule #配置规则 响应时间权重
# com.netflix.loadbalancer.BestAvailableRule #配置规则 最空闲连接策略
1 2 3
| USERPROVIDER: ribbon: NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RoundRobinRule
|
引入依赖
1 2 3 4 5
| <dependency> <groupId>org.springframework.retry</groupId> <artifactId>spring-retry</artifactId> </dependency>
|
配置文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| spring: cloud: loadbalancer: retry: enabled: true USERPROVIDER: ribbon: NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RoundRobinRule ConnectTimeout: 250 ReadTimeout: 250 OkToRetryOnAllOperations: true MaxAutoRetriesNextServer: 1 MaxAutoRetries: 1
|
3、服务调用基于Feign
1 2 3 4
| <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>
|
- 修改应用启动类,增加注解@EnableFeignClients
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| package com.syl.userweb;
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.cloud.openfeign.EnableFeignClients; import org.springframework.context.annotation.Bean; import org.springframework.web.client.RestTemplate;
@SpringBootApplication @EnableDiscoveryClient @EnableFeignClients public class UserWeb04Application { @Bean @LoadBalanced public RestTemplate restTemplate(){ return new RestTemplate(); } public static void main(String[] args) { SpringApplication.run(UserWeb04Application.class, args); } }
|
- 修改接口UserService.java,删除实现类UserServiceImpl
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| package com.syl.userweb.service;
import com.syl.userweb.entity.User; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.*;
import java.util.Map;
@FeignClient("USERPROVIDER") public interface UserService { @GetMapping("/user/getall") public Map getUserMap(); @PostMapping("/user/save") public void createUser(User user); @GetMapping("/user/get/{id}") public User getUser( @RequestParam("id") Integer id); @PutMapping("/user/update/{id}") public void updateUser(@RequestParam("id") Integer id, User user); @DeleteMapping("/user/delete/{id}") public void deleteUser( @RequestParam("id") Integer id); }
|
熔断器组件Netflix Hystrix
1、Ribbon使用Hystix
基于消费方03模块修改
1 2 3 4 5
| <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency>
|
- 修改应用启动类。增加注解@EnableCircuitBreaker
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| package com.syl.userweb;
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 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;
@SpringBootApplication @EnableDiscoveryClient @EnableCircuitBreaker public class UserWeb03Application {
@Bean @LoadBalanced public RestTemplate restTemplate(){ return new RestTemplate(); } public static void main(String[] args) { SpringApplication.run(UserWeb03Application.class, args); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
| package com.syl.userweb.service.impl;
import com.netflix.appinfo.InstanceInfo;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; import com.syl.userweb.entity.User; import com.syl.userweb.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient; import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate;
import java.lang.reflect.Field; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map;
@Service public class UserServiceImpl implements UserService { @Autowired RestTemplate restTemplate;
String url = "http://USERPROVIDER/user";
public Map<String, Object> getUserMapFallbackMethod() { System.out.println("调用失败!"); Map map = new HashMap(); map.put("list", new ArrayList<>()); map.put("ProviderVersion", "获取远程调用失败"); return map;
} @Override @HystrixCommand(fallbackMethod = "getUserMapFallbackMethod") public Map getUserMap () { long beginTime = System.currentTimeMillis(); Map map = restTemplate.getForObject(url + "/getall", Map.class); long endTime = System.currentTimeMillis(); System.out.println("程序执行时间:" + (endTime - beginTime));
return map; }
@Override public void createUser (User user){ restTemplate.postForObject(url + "r/save", user, String.class); }
@Override public User getUser (Integer id){ return restTemplate.getForObject(url + "/get/" + id, User.class); }
@Override public void updateUser (Integer id, User user){ restTemplate.put(url + "/update/" + id, user); }
@Override public void deleteUser (Integer id){ restTemplate.delete(url + "/delete/" + id); } }
|
默认超时时间为1000ms,可以在配置文件中配置,为了项目的正常运行,熔断时间一定大于超时时间
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| USERPROVIDER: ribbon: NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RoundRobinRule ConnectTimeout: 250 ReadTimeout: 250 OkToRetryOnAllOperations: true MaxAutoRetriesNextServer: 1 MaxAutoRetries: 1 hystrix: command: default: execution: isolation: thread: timeoutInMilliseconds: 6000
|
2、Feign使用Hystix
1 2 3 4 5 6 7 8 9 10 11 12
| feign: hystrix: enabled: true
hystrix: command: default: execution: isolation: thread: timeoutInMilliseconds: 6000
|
- 编写Feign声明接口UserService的实现类UserServiceImpl(注意要声明为@Service)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| package com.syl.userweb.service.impl;
import com.syl.userweb.entity.User; import com.syl.userweb.service.UserService; import org.springframework.stereotype.Service;
import java.util.ArrayList; import java.util.HashMap; import java.util.Map;
@Service public class UserServiceImpl implements UserService { @Override public Map getUserMap() { System.out.println("请求失败"); Map map = new HashMap(); map.put("list", new ArrayList<>()); map.put("ProviderVersion", "获取远程调用失败"); return map;
}
@Override public void createUser(User user) { System.out.println("创建用户失败:"+user); }
@Override public User getUser(Integer id) { System.out.println("获取id:"+id+" 的用户失败"); return null;
}
@Override public void updateUser(Integer id, User user) { System.out.println("更新id:"+id+"的用户失败"); }
@Override public void deleteUser(Integer id) { System.out.println("删除id为:"+id+"的用户失败"); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| package com.syl.userweb.util;
import feign.Contract; import feign.Logger; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;
@Configuration public class FeignConfiguration {
@Bean public Logger.Level getFeignlogger(){ return Logger.Level.FULL; } }
|
- 在Feign调用接口UserService中,使用注解@FeignClient声明熔断调用实现类
1
| @FeignClient(value="USERPROVIDER",configuration= FeignConfiguration.class,fallback= UserServiceImpl.class)
|
重启项目验证
3、 Hystix监控服务器搭建
- 新建一个springBoot模块hystrix-dashboard ,添加依赖
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
| <?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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>com.syl</groupId> <artifactId>springcloud01</artifactId> <version>1.0-SNAPSHOT</version> </parent> <groupId>com.syl</groupId> <artifactId>hystrix-dashboard</artifactId> <version>0.0.1-SNAPSHOT</version> <name>hystrix-dashboard</name> <description>Demo project for Spring Boot</description>
<properties> <java.version>1.8</java.version> <spring-cloud.version>Hoxton.RC1</spring-cloud.version> <spring-boot.version>2.2.0.RELEASE</spring-boot.version> <hystrix.version>2.2.0.RC1</hystrix.version> </properties>
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> <version>${spring-boot.version}</version> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> <version>${hystrix.version}</version> </dependency>
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId> <version>${hystrix.version}</version> </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>
<dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
<repositories> <repository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/milestone</url> </repository> </repositories>
</project>
|
- 为应用主类加上@EnableHystrixDashboard,启用Hystrix Dashboard功能
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| package com.syl.hystrixdashboard;
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;
@SpringBootApplication @EnableHystrixDashboard public class HystrixDashboardApplication {
public static void main(String[] args) { SpringApplication.run(HystrixDashboardApplication.class, args); }
}
|
1 2 3 4 5
| spring: application: name: hystrix-dashboard server: port: 1301
|
浏览器访问http://localhost:1301/hystrix测试
4、启用客户端Hystix监控
- 修改项目消费方04的pom.xml增加Hystrix监控所需依赖包
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| <properties> <hystrix.version>2.2.0.RC1</hystrix.version> </properties>
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> <version>${hystrix.version}</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| package com.syl.userweb;
import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServlet; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.web.servlet.ServletRegistrationBean; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.cloud.netflix.hystrix.EnableHystrix; import org.springframework.cloud.openfeign.EnableFeignClients; import org.springframework.context.annotation.Bean; import org.springframework.web.client.RestTemplate;
@SpringBootApplication @EnableDiscoveryClient @EnableFeignClients @EnableHystrix public class UserWeb04Application {
@Bean @LoadBalanced public RestTemplate restTemplate(){ return new RestTemplate(); }
public static void main(String[] args) {
SpringApplication.run(UserWeb04Application.class, args); }
@Bean public ServletRegistrationBean getServlet(){ HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet(); ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet); registrationBean.setLoadOnStartup(1); registrationBean.addUrlMappings("/hystrix.stream"); registrationBean.setName("HystrixMetricsStreamServlet"); return registrationBean; } }
|
首先 http://localhost:10089/ 访问正常项目
其次 http://localhost:9004/hystrix.stream 查看数据监控
输入 http://localhost:1301/hystrix访问Hystrix Dashboard的首页
在Hystrix Dashboard的首页输入 http://localhost:9004/hystrix.stream 点击Monitor Stream查看图形化监控
分布式配置中心组件Spring Cloud Config
1、构建Config Server
- 新建模块ConfigServer001,修改pom.xml引入所需依赖
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
| <?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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>com.syl</groupId> <artifactId>springcloud01</artifactId> <version>1.0-SNAPSHOT</version> </parent> <groupId>com.syl</groupId> <artifactId>config-server01</artifactId> <version>0.0.1-SNAPSHOT</version> <name>config-server01</name> <description>Demo project for Spring Boot</description>
<properties> <java.version>1.8</java.version> <spring-cloud.version>Hoxton.RC1</spring-cloud.version> </properties>
<dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-config-server</artifactId> </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>
<dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
<repositories> <repository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/milestone</url> </repository> </repositories>
</project>
|
- 修改启动程序,并添加@EnableConfigServer注解,开启Config Server
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| package com.syl.configserver01;
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.config.server.EnableConfigServer;
@SpringBootApplication @EnableConfigServer public class ConfigServer01Application {
public static void main(String[] args) { SpringApplication.run(ConfigServer01Application.class, args); }
}
|
- 修改配置文件application.yml配置服务信息以及git信息
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| server: port: 7001
spring: application: name: config-server cloud: config: server: git: uri: https://github.com/WINNER003/SpringBootServerConfig search-paths: src/main/resources username: WINNER003 password: ***
|
URL与配置文件的映射关系如下:
/{application}/{profile}[/{label}]
/{application}-{profile}.yml
/{label}/{application}-{profile}.yml
/{application}-{profile}.properties
/{label}/{application}-{profile}.properties
上面的url会映射{application}-{profile}.properties对应的配置文件,{label}对应git上不同的分支,默认为master。
2、Config Client客户端调用配置中心配置,并实现动态刷新——有待进一步测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency>
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
|
- 将原来的配置文件清空,在同级目录下创建bootstrap.yml文件
1 2 3 4 5 6 7 8
| spring: application: name: UserProvdier01 cloud: config: uri: http://localhost:7001 profile: test label: master
|
- 在application.yml文件里开启自动刷新
1 2 3 4 5
| management: endpoints: web: exposure: include: refresh,health,info
|
- 在UserController控制器上添加注解@RefreshScope
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| @RestController @RequestMapping("/user") @RefreshScope public class UserController {
@Autowired UserService userService;
@Value("${ProviderVersion}") private String providerVersion;
@GetMapping("/getall") public Map<String,Object> getUsers() { try { System.out.println("睡眠"); int i = new Random().nextInt(6000); System.out.println(i+"ms"); Thread.sleep(i); } catch (InterruptedException e) { e.printStackTrace(); }
Map<String,Object> map=new HashMap<>(); List<User> list = userService.getUserList(); map.put("list", list); map.put("ProviderVersion", providerVersion); return map; }
|
3、高可用ConfigServer
1 2 3 4 5
| <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency>
|
1 2 3 4 5 6
| eureka: client: service-url: defaultZone: http://localhost:8888/eureka,http://localhost:8889/eureka
|
- 启动类添加@EnableDiscoveryClient
1 2 3 4 5 6 7 8 9 10
| @SpringBootApplication @EnableConfigServer @EnableDiscoveryClient public class ConfigServer001Application {
public static void main(String[] args) { SpringApplication.run(ConfigServer001Application.class, args); } }
|
- 复制config-server01创建模块config-server002,更改端口号 其他不变
- 配置客户端使用高可用配置中心,确保客户端项目UserProvdier01的pom.xml的有使用Eureka的客户端包
1 2 3 4
| <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency>
|
- 修改bootstrap.yml文件 注意cloud一定要在eureka配置项之前
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| spring: application: name: UserProvdier01 cloud: config: discovery: enabled: true service-id: config-server profile: test label: master eureka: client: service-url: defaultZone: http://localhost:8888/eureka,http://localhost:8889/eureka
|
- 修改项目启动类,增加@EnableDiscoveryClient注解
重启项目,测试
服务网关组件Netflix Zuul