Spring cloud 实现服务注册(分布式、负载均衡、微服务集群)


基础服务组件(配置文件存放)服务组件(数据库应用服务器)web服务器(SpringMVC/servlet/api网关)
|↑↓↑
|服务发现|注册服务发现
←———————————→eureka服务器—————————
服务注册/发现




注释:API网关是一个服务器,是系统的唯一入口。系统的后端总入口。有以下两种方式:
单节点API网关:单节点的API网关为每个客户端提供不同的API,而不是提供一种万能风格的API。
Backends for frontends网关:这种模式是针对不同的客户端来实现一个不同的API网关
目前流行的网关:
Tyk开放源码的API网关,它是快速、可扩展和现代的。Tyk提供了一个API管理平台,其中包括API网关、API分析、开发人员门户和API管理面板。Try 是一个基于Go实现的网关服务。
Kong可扩展的开放源码API Layer(也称为API网关或API中间件)。Kong 在任何RESTful API的前面运行,通过插件扩展,它提供了超越核心平台的额外功能和服务。
Orange和Kong类似也是基于OpenResty的一个API网关程序,是由国人开发的,学姐也是贡献者之一。
Netflix/zuulZuul是一种提供动态路由、监视、弹性、安全性等功能的边缘服务。Zuul是Netflix出品的一个基于JVM路由和服务端的负载均衡器。
apiaxleNodejs实现的一个API网关。
api-umbrellaRuby实现的一个API网关。
第一步创建git工程
cloud-config-repo配置文件存放的文件夹
cloud-simple-service数据库应用服务器1
cloud-simple-service数据库应用服务器2
cloud-config-server配置管理服务器
cloud-eureka-servereureka注册服务器
cloud-simple-ui客户端
.gitignore默认配置
README.md说明文档


第二步配置pom.xml
<?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>cloud</groupId>
<artifactId>cloud-config-server</artifactId>
<version>0.0.1</version>
<packaging>jar</packaging>
<name>cloud-config-serve</name>
<description>cloud-config-server</description>
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-parent</artifactId>
<version>Brixton.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.7</java.version>
</properties>
<repositories>
<repository>
<snapshots>
<enabled>true</enabled>
</snapshots>
<id>public</id>
<name>Public Repositories</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
</repository>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>http://repo.spring.io/libs-snapshot-local</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>http://repo.spring.io/libs-milestone-local</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>spring-releases</id>
<name>Spring Releases</name>
<url>http://repo.spring.io/libs-release-local</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>public</id>
<name>Public Repositories</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
</pluginRepository>
</pluginRepositories>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
<defaultGoal>compile</defaultGoal>
</build>
</project>


第三步:在cloud-config-repo目录下创建两个配置文件
cloud-config-dev.properties//开发环境配置文件
cloud-config-test.properties//测试环境配置信息,目前都相同吧
mysqldb.datasource.url=jdbc\:mysql\://123.207.16.155\:3306/test?useUnicode\=true&characterEncoding\=utf-8
mysqldb.datasource.username=csst
mysqldb.datasource.password=csst
logging.level.org.springframework.web:DEBUG


第四步:创建配置管理服务器cloud-config-server
ConfigServerApplication.java
@SpringBootApplication
@EnableConfigServer//激活该应用为配置文件服务器
public class ConfigServerApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigServerApplication.class, args);
}
}
application.properties
#配置当前 web 应用绑定 8888 端口
server.port=8888
#指定配置文件所在的 git 工程路径
spring.cloud.config.server.git.uri=https://gitee.com/anlemusic/Test.git
#searchPaths表示将搜索该文件夹下的配置文件
spring.cloud.config.server.git.searchPaths=cloud-config-repo
pom.xml
最后,还需要在 pom 文件中增加配置服务器的相关依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>


第五步:创建数据库
CREATE TABLE `user` (`id` varchar(50) NOT NULL DEFAULT '',
`username` varchar(50) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


第六步:cloud-simple-service的数据库应用的配置(执行时两次,不同的端口)
DataSourceProperties.java
package cloud.simple.service.conf;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties(prefix = DataSourceProperties.DS, ignoreUnknownFields = false)
public class DataSourceProperties {
//对应配置文件里的配置键
public final static String DS="mysqldb.datasource";
private String driverClassName ="com.mysql.jdbc.Driver";
private String url; 
private String username; 
private String password;
private int maxActive = 100;
private int maxIdle = 8;
private int minIdle = 8;
private int initialSize = 10;
private String validationQuery;
public String getDriverClassName() {
return driverClassName;
}
public void setDriverClassName(String driverClassName) {
this.driverClassName = driverClassName;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public int getMaxActive() {
return maxActive;
}
public void setMaxActive(int maxActive) {
this.maxActive = maxActive;
}
public int getMaxIdle() {
return maxIdle;
}
public void setMaxIdle(int maxIdle) {
this.maxIdle = maxIdle;
}
public int getMinIdle() {
return minIdle;
}
public void setMinIdle(int minIdle) {
this.minIdle = minIdle;
}
public int getInitialSize() {
return initialSize;
}
public void setInitialSize(int initialSize) {
this.initialSize = initialSize;
}
public String getValidationQuery() {
return validationQuery;
}
public void setValidationQuery(String validationQuery) {
this.validationQuery = validationQuery;
}
public boolean isTestOnBorrow() {
return testOnBorrow;
}
public void setTestOnBorrow(boolean testOnBorrow) {
this.testOnBorrow = testOnBorrow;
}
public boolean isTestOnReturn() {
return testOnReturn;
}
public void setTestOnReturn(boolean testOnReturn) {
this.testOnReturn = testOnReturn;
}
private boolean testOnBorrow = false;
private boolean testOnReturn = false;
}
MybatisDataSource.java
package cloud.simple.service.conf;
import javax.annotation.PreDestroy;
import javax.sql.DataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
@Configuration
@EnableConfigurationProperties(DataSourceProperties.class)
//mybaits dao 搜索路径
@MapperScan("cloud.simple.service.dao")
public class MybatisDataSource {
@Autowired
private DataSourceProperties dataSourceProperties;
//mybaits mapper xml搜索路径
private final static String mapperLocations="classpath:cloud/simple/service/dao/*.xml"; 
private org.apache.tomcat.jdbc.pool.DataSource pool;
@Bean(destroyMethod = "close")
public DataSource dataSource() {
DataSourceProperties config = dataSourceProperties;
this.pool = new org.apache.tomcat.jdbc.pool.DataSource();
this.pool.setDriverClassName(config.getDriverClassName());
this.pool.setUrl(config.getUrl());
if (config.getUsername() != null) {
this.pool.setUsername(config.getUsername());
}
if (config.getPassword() != null) {
this.pool.setPassword(config.getPassword());
}
this.pool.setInitialSize(config.getInitialSize());
this.pool.setMaxActive(config.getMaxActive());
this.pool.setMaxIdle(config.getMaxIdle());
this.pool.setMinIdle(config.getMinIdle());
this.pool.setTestOnBorrow(config.isTestOnBorrow());
this.pool.setTestOnReturn(config.isTestOnReturn());
this.pool.setValidationQuery(config.getValidationQuery());
return this.pool;
}
@PreDestroy
public void close() {
if (this.pool != null) {
this.pool.close();
}
}
@Bean
public SqlSessionFactory sqlSessionFactoryBean() throws Exception {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource());
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
sqlSessionFactoryBean.setMapperLocations(resolver.getResources(mapperLocations));
return sqlSessionFactoryBean.getObject();
}
@Bean
public PlatformTransactionManager transactionManager() {
return new DataSourceTransactionManager(dataSource());
}
}
UserDao.java
package cloud.simple.service.dao;
import java.util.List;
import cloud.simple.service.model.User;
public interface UserDao {
List<User> findAll();
}
UserService.java
package cloud.simple.service.domain;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import cloud.simple.service.dao.UserDao;
import cloud.simple.service.model.User;
@Service
@Transactional
public class UserService {
@Autowired
private UserDao userMapper;
public List<User> searchAll(){
List<User> list = userMapper.findAll();
return list;
}
}
User.java
package cloud.simple.service.model;
public class User {
private String username;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}
UserController.java
package cloud.simple.service.web;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import cloud.simple.service.domain.UserService;
import cloud.simple.service.model.User;
@RestController
public class UserController {
@Autowired
UserService userService;
@RequestMapping(value="/user",method=RequestMethod.GET)
public List<User> readUserInfo(){
List<User> ls=userService.searchAll();
return ls;
}
}
src\main\resources\cloud\simple\service\dao
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cloud.simple.service.dao.UserDao">
  <select id="findAll" resultType="cloud.simple.service.model.User">
    select * from user
  </select>
</mapper>
src\main\resources\bootstrap.properties
#指定远程加载配置信息的地址
#${config.port:8888}如果在命令行提供了config.port 参数,我们就用这个端口,否则就用 8888 端口
spring.cloud.config.uri=http://127.0.0.1:${config.port:8888}
#配置文件名称config.name为simple-service,config.profile为dev.即{application}-{profile}.properties=cloud-config-dev.properties
spring.cloud.config.name=cloud-config
spring.cloud.config.profile=${config.profile:dev}
#service discovery url
eureka.client.serviceUrl.defaultZone=http\://localhost\:8761/eureka/,http\://zlhost\:8762/eureka/
#service name
spring.application.name=cloud-simple-service
server.port=8081


第七步:创建cloud-eureka-server 注册服务器
所有的服务端及访问服务的客户端都需要连接到注册管理器( eureka 服务器)。服务在启动时
会自动注册自己到 eureka 服务器,每一个服务都有一个名字,这个名字会被注册到 eureka 服务
器。使用服务的一方只需要使用该名字加上方法名就可以调用到服务。
pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
<dependency>
        <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>  
</dependencies>
EurekaServer.java
@SpringBootApplication
//使用@EnableEurekaServer 注解就可以让应用变为 Eureka 服务器
@EnableEurekaServer
public class EurekaServer {
public static void main(String[] args) {
SpringApplication.run(EurekaServer.class, args);
}
}
application.properties
#server.port 配置 eureka 服务器端口号
server.port=8761
eureka.instance.hostname=localhost
#是否注册自身到 eureka 服务器
eureka.client.registerWithEureka=false
#是否从 eureka 服务器获取注册信息
eureka.client.fetchRegistry=false
#设置 eureka 服务器所在的地址,查询服务和注册服务都需要依赖这个地址。
eureka.client.serviceUrl.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka/
#manager url:http://localhost:8761/


//其他服务使用eureka服务器,只需添加@EnableDiscoveryClient注解就可以了
//然后在其配置文件中添加:
//eureka.client.serviceUrl.defaultZone=http\://localhost\:8761/eureka/
//spring.application.name=cloud-simple-service
//pom 文件也需要增加:
//<dependency>
//<groupId>org.springframework.cloud</groupId>
//<artifactId>spring-cloud-starter-eureka</artifactId>
//</dependency>








第八步:创建cloud-simple-ui客户端
在spring boot中已经不推荐使用jsp,所以你如果使用jsp来实现ui端将会很麻烦.
这可能跟现在的开发主流偏重移动端有关,跟微服务有关,跟整个时代当前的技术需求有关。
单纯以html来作为客户端,有很多好处.比如更利于使用高速缓存、使后台服务无状态话、更利于处理高并发、更利于页面作为服务、小服务组合成大服务等。
User.java
package cloud.simple.model;
public class User {
private String username;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}
WebApplication.java
@SpringBootApplication
//配置本应用将使用服务注册和服务发现
@EnableEurekaClient
//示启用断路器,断路器依赖于服务注册和发现
@EnableHystrix
public class WebApplication {
public static void main(String[] args) throws Exception {
SpringApplication.run(WebApplication.class, args);
}
}
UserService.java
@Service
public class UserService {
@Autowired
RestTemplate restTemplate;//restTemplate进行服务调用
final String SERVICE_NAME="cloud-simple-service";
//断路器的基本作用就是@HystrixCommand注解的方法失败后,系统将自动切换到fallbackMethod方法执行(回退机制)
//使用该功能允许快速失败并迅速恢复或者回退并优雅降级
@HystrixCommand(fallbackMethod = "fallbackSearchAll")
public List<User> searchAll() {
return restTemplate.getForObject("http://"+SERVICE_NAME+"/user", List.class);
}
private List<User> fallbackSearchAll() {
System.out.println("HystrixCommand fallbackMethod handle!");
List<User> ls = new ArrayList<User>();
User user = new User();
user.setUsername("TestHystrix");
ls.add(user);
return ls;
}
}
UserController.java
@RestController
public class UserController {
@Autowired
UserService userService;
@RequestMapping(value="/users")
public ResponseEntity<List<User>> readUserInfo(){
List<User> users=userService.searchAll();
return new ResponseEntity<List<User>>(users,HttpStatus.OK);
} }
index.html
<html ng-app="users">
<head>
<script src="http://cdn.bootcss.com/angular.js/1.3.18/angular.min.js"></script>
<script src="http://cdn.bootcss.com/angular.js/1.3.18/angular-route.js"></script>
<script src="js/app.js"></script>
</head>
<body>
<div ng-view class="container">
</div>
</body>
</html>
user-page.html
<div>
<ul ng-controller="userCtr">
<li ng-repeat="item in userList">
{{item.username}}
</li>
</ul>
</div>
app.js
angular.module('users', ['ngRoute']).config(function ($routeProvider) {
$routeProvider.when('/', {
templateUrl: 'user-page.html',
controller: 'userCtr'
})
}).controller('userCtr', function ($scope, $http) {
$http.get('users').success(function (data) {
//alert(data+"");
$scope.userList = data;
});
});
//使用了angularJS库
bootstrap.properties 
spring.cloud.config.uri=http://127.0.0.1:${config.port:8888}
spring.cloud.config.name=cloud-config
spring.cloud.config.profile=${config.profile:dev}
eureka.client.serviceUrl.defaultZone=http\://localhost\:8761/eureka/
spring.application.name=simple-ui-phone
pom.xml(因为使用了断路器,加入hystrix依赖)
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
log4j.properties
log4j.rootCategory=INFO, CONSOLE
PID=????
LOG_PATTERN=[%d{yyyy-MM-dd HH:mm:ss.SSS}] log4j%X{context} - ${PID} %5p [%t] --- %c{1}: %m%n
# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=${LOG_PATTERN}
log4j.category.org.hibernate.validator.internal.util.Version=INFO
log4j.category.org.apache.coyote.http11.Http11NioProtocol=INFO
log4j.category.org.apache.tomcat.util.net.NioSelectorPool=INFO
log4j.category.org.apache.catalina.startup.DigesterFactory=INFO
log4j.logger.org.apache=INFO


剩下最重要的事情就是进行部署了,我们以此使用命令启动这些服务及应用:
java -jar cloud-config-server-0.0.1.jar启动配置服务器,固定绑定端口8888
java -jar cloud-eureka-server-1.0.0.jar启动注册服务器,固定绑定端口8671
java -jar cloud-simple-service-1.0.0.jar --server.port=8081 >log8081.log启动后台服务,绑定端口8081
java -jar cloud-simple-service-1.0.0.jar --server.port=8082 >log8082.log启动后台服务,绑定端口8082
java -jar cloud-simple-ui-1.0.0.jar --server.port=8080 >log8080.log启动前端 ui 应用,绑定端口8080
运行 http://localhost:8080/即可看到运行的结果。其中“>log8080.log”表示输出日志到文件。
这里运行了两个cloud-simple-service实例,主要是为了演示ribbon负载均衡。默认情况下使用
ribbon不需要再作任何配置,不过它依赖于注册服务器。


















docker发布spring cloud应用
Docker是一种虚拟机技术,在 linux 虚拟机技术 LXC 基础上又封装了一层,是基于 LXC 的容器技术。
可以把容器看做是一个简易版的 Linux 环境(包括 root 用户权限、进程空间、用户空间和网络空间等)
和运行在其中的应用程序。容器是用来装东西的,Docker 可以装载应用本身及其运行环境进容器
这是一个很小的文件,然后把这个文件扔到任何兼容的服务器上就可以运行,也是基于这一点
Docker 可以同时让应用的部署、测试和分发都变得前所未有的高效和轻松!




创建cloud-simple-docker一个简单的spring boot应用
MusicApplication.java
@SpringBootApplication
@RestController
public class MusicApplication {
@RequestMapping("/")
public String home() {
return "Hello Docker World";
}


public static void main(String[] args) {
SpringApplication.run(MusicApplication.class, args);
}
}
创建src/main/docker/Dockerfile文件
#------------------------------------------------------------------------------------
# 基于那个镜像
FROM daocloud.io/java:8
# 将本地文件夹挂载到当前容器(tomcat使用)
VOLUME /tmp
# 拷贝文件到容器
ADD cloud-simple-docker-1.0.0.jar /app.jar
# 打开服务端口
EXPOSE 8080
# 配置容器启动后执行的命令
RUN bash -c 'touch /app.jar'
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
#------------------------------------------------------------------------------------
Pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.5.RELEASE</version>
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Brixton.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<properties>
<docker.image.prefix>springio</docker.image.prefix>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.7</java.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-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
部署dockeryum -y install docker-io(Linux请先安装)
将编译后的 jar 文件考到服务器某个目录,这里是 tmp 目录。然后将 Dockerfile 也考到该目
录,最后进入到该目录下运行命令(后面有个点):docker build -t local/cloud-simple-docker .
(此处后应内核版本低没有亲自尝试)
运行成功后,就创建了一个镜像,可以使用 docker images 来查看该镜像。
有了镜像就可以运行了,使用下面命令运行:
docker run -p 8080:8080 –t local/cloud-simple-docker
其中 8080:8080 表示本机端口映射到 Docker 实例端口
成功后可以使用 docker ps –a查看镜像运行情况:
local/cloud-simple-docker | latest | 3ef51d55eb27 | 22 minutes ago | 667.2 MB
可以看到这个包括了 java 运行环境的 web 应用镜像是667MB










使用spring boot和thrift、zookeeper建立微服务
thrift:由Facebook开发的远程服务调用框架Apache Thrift,它采用接口描述语言定义并创建服务,支持可扩展的跨语言服务开发
所包含的代码生成引擎可以在多种语言中,如 C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, Smalltalk
等创建高效的、无缝的服务,其传输数据采用二进制格式,相对 XML 和 JSON 体积更小,对于高并发、大数据量和多语言的环境更有优势。
zookeeper:
cloud-thrift-interface接口及传输对象定义
cloud-thrift-server服务提供方
cloud-thrift-client服务调用方




第一步:cloud-thrift-interface
pom.xml
<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>cloud.simple</groupId>
<artifactId>cloud-thrift-interface</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>cloud-thrift-interface</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.7</java.version>
</properties>
<repositories>
<repository>
<snapshots>
<enabled>true</enabled>
</snapshots>
<id>public</id>
<name>Public Repositories</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>public</id>
<name>Public Repositories</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
</pluginRepository>
</pluginRepositories>
<dependencies>
<dependency>
<groupId>org.apache.thrift</groupId>
<artifactId>libthrift</artifactId>
<version>0.9.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
<defaultGoal>compile</defaultGoal>
</build>
</project>


创建src\main\resources\UserService.thrift
namespace java cloud.simple.service
struct UserDto {
1: i32 id
2: string username
}
service UserService {
UserDto getUser()
}
http://apache.fayea.com/thrift/可下载随意版本,放入文件夹,加入环境变量
执行thrift -gen java %Path%UserService.thrift
接口定义完后,使用 thrift 命令生成对应的 java 文件,主要生成两个文件,分别是
UserService.java 和 UserDto.java,把这两个文件放入 cloud-thrift-interface 工程,因为客户端也需
要这个接口定义。




第二步:cloud-thrift-server
pom.xml
<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>cloud.simple</groupId>
<artifactId>cloud-thrift-server</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>cloud-thrift-server</name>
<url>http://maven.apache.org</url>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.3.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<repositories>
<repository>
<snapshots>
<enabled>true</enabled>
</snapshots>
<id>public</id>
<name>Public Repositories</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>public</id>
<name>Public Repositories</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
</pluginRepository>
</pluginRepositories>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.7</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.thrift</groupId>
<artifactId>libthrift</artifactId>
<version>0.9.1</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.1</version>
</dependency>
<!-- 引入cloud-thrift-interface -->
<dependency>
<groupId>cloud.simple</groupId>
<artifactId>cloud-thrift-interface</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!-- zookeeper -->
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.6</version>
</dependency>
<dependency>
<groupId>org.apache.helix</groupId>
<artifactId>helix-core</artifactId>
<version>0.6.4</version>
</dependency>
<!-- zookeeper -->
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
<defaultGoal>compile</defaultGoal>
</build>
</project>
ThriftConfig.java
@Configuration
public class ThriftConfig {
// 创建一个使用单个 worker 线程的 Executor,以无界队列方式来运行该线程
ExecutorService executor = Executors.newSingleThreadExecutor();
@Bean
public TServerTransport tServerTransport() {
try {
return new TServerSocket(7911);
} catch (TTransportException e) {
e.printStackTrace();
}
return null;
}
@Bean
public TServer tServer() {
// 在服务的提供端需要实现接口,并且还要把实现类注册到 thrift 服务器。
UserService.Processor processor = new UserService.Processor(new UserServiceImpl());
// UserServiceImpl 就是接口实现类,将其注册为Tserver。
TServer server = new TThreadPoolServer(new TThreadPoolServer.Args(tServerTransport()).processor(processor));
return server;
}
// 注册完服务后,需要启动 TServer,很显然这个需要在线程里启动。
@PostConstruct
public void init() {
executor.execute(new Runnable() {
@Override
public void run() {
tServer().serve();
}
});
}
}
使用zookeeper进行服务名称注册
上面是注册具体的服务执行类,这一步是将服务的实例注册进 zookeeper,这样才能实现负载均
衡。让客户端可以根据服务实例列表选择服务来执行。当然这里只需要注册服务所在服务器的 IP
即可,因为客户端只要知道 IP,也就知道访问那个 IP 下的该服务。
ZooKeeperConfig.java
@Configuration
public class ZooKeeperConfig {
@Value("${service.name}")
String serviceName;
@Value("${zookeeper.server.list}")
String serverList;
ExecutorService executor = Executors.newSingleThreadExecutor();
@PostConstruct
public void init() {
executor.execute(new Runnable() {
@Override
public void run() {
registService();
try {
Thread.sleep(1000 * 60 * 60 * 24 * 360 * 10);// 休眠十年(注册服务十年)
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
// 注册服务
public ZkClient registService() {
String servicePath = "/" + serviceName;// 根节点路径
ZkClient zkClient = new ZkClient(serverList);
boolean rootExists = zkClient.exists(servicePath);
if (!rootExists) {
zkClient.createPersistent(servicePath);
}
InetAddress addr = null;
try {
addr = InetAddress.getLocalHost();
} catch (UnknownHostException e) {
e.printStackTrace();
}
String ip = addr.getHostAddress().toString();
String serviceInstance = System.nanoTime() + "-" + ip;
// zkClient.createEphemeral建立临时节点,如果这台服务器宕机,这个临时节点是会被清除的,这样客户端在访问时就不会再选择该服务器上的服务。
zkClient.createEphemeral(servicePath + "/" + serviceInstance);
System.out.println("提供的服务为:" + servicePath + "/" + serviceInstance);
return zkClient;
}
}
application.properties
service.name=cloud-thrift-service
zookeeper.server.list=127.0.0.1\:2181


第三步:cloud-thrift-client
pom.xml
<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>cloud.simple</groupId>
<artifactId>cloud-thrift-client</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>cloud-thrift-client</name>
<url>http://maven.apache.org</url>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.3.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<repositories>
<repository>
<snapshots>
<enabled>true</enabled>
</snapshots>
<id>public</id>
<name>Public Repositories</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>public</id>
<name>Public Repositories</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
</pluginRepository>
</pluginRepositories>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.7</java.version>
</properties>


<dependencies>
<!--web应用基本环境配置 -->
<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>
<dependency>
<groupId>cloud.simple</groupId>
<artifactId>cloud-thrift-interface</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!-- zookeeper -->
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.6</version>
</dependency>
<dependency>
<groupId>org.apache.helix</groupId>
<artifactId>helix-core</artifactId>
<version>0.6.4</version>
</dependency>
<!-- zookeeper -->
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
<defaultGoal>compile</defaultGoal>
</build>
</project>
ZooKeeperConfig.java
@Configuration
public class ZooKeeperConfig {
@Value("${service.name}")
String serviceName;
@Value("${zookeeper.server.list}")
String zookeeperList;
ExecutorService executor = Executors.newSingleThreadExecutor();
// thrift实例列表
public static Map<String, UserService.Client> serviceMap = new HashMap<String, UserService.Client>();
@PostConstruct
private void init() {
executor.execute(new Runnable() {
@Override
public void run() {
startZooKeeper();
try {
Thread.sleep(1000 * 60 * 60 * 24 * 360 * 10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
// 注册服务
private void startZooKeeper() {
List<String> currChilds = new ArrayList<String>();
String servicePath = "/" + serviceName;// 根节点路径
ZkClient zkClient = new ZkClient(zookeeperList);
boolean serviceExists = zkClient.exists(servicePath);
if (serviceExists) {
currChilds = zkClient.getChildren(servicePath);
} else {
throw new RuntimeException("service not exist!");
}
for (String instanceName : currChilds) {
// 没有该服务,建立该服务
if (!serviceMap.containsKey(instanceName)) {
serviceMap.put(instanceName, createUserService(instanceName));
}
}
// 注册事件监听
zkClient.subscribeChildChanges(servicePath, new IZkChildListener() {
// @Override
public void handleChildChange(String parentPath, List<String> currentChilds) throws Exception {
// 实例(path)列表:当某个服务实例宕机,实例列表内会减去该实例
for (String instanceName : currentChilds) {
// 没有该服务,建立该服务
if (!serviceMap.containsKey(instanceName)) {
serviceMap.put(instanceName, createUserService(instanceName));
}
}
for (Map.Entry<String, UserService.Client> entry : serviceMap.entrySet()) {
// 该服务已被移除
if (!currentChilds.contains(entry.getKey())) {
UserService.Client c = serviceMap.get(entry.getKey());
try {
c.getInputProtocol().getTransport().close();
c.getOutputProtocol().getTransport().close();
} catch (Exception e) {
e.printStackTrace();
}
serviceMap.remove(entry.getKey());
}
}
System.out.println(parentPath + "事件触发");
}
});
}
// 创建一个服务实例
private UserService.Client createUserService(String serviceInstanceName) {
String ip = serviceInstanceName.split("-")[1];
TSocket transport = new TSocket(ip, 7911);
try {
transport.open();
} catch (TTransportException e) {
e.printStackTrace();
}
return new UserService.Client(new TBinaryProtocol(transport));
}
}
UserServiceProvider.java
@Component
public class UserServiceProvider {
public UserService.Client getBalanceUserService(){
Map<String, UserService.Client> serviceMap =ZooKeeperConfig.serviceMap;
//以负载均衡的方式获取服务实例
for (Map.Entry<String, UserService.Client> entry : serviceMap.entrySet()) {
System.out.println("可供选择服务:"+entry.getKey());
}
int rand=new Random().nextInt(serviceMap.size());
String[] mkeys = serviceMap.keySet().toArray(new String[serviceMap.size()]);
return serviceMap.get(mkeys[rand]);
}
}
UserController.java
@Controller
public class UserController {
@Autowired
UserServiceProvider userServiceProvider;
@ResponseBody
@RequestMapping(value = "/hello")
String hello() throws TException {
UserService.Client svr=userServiceProvider.getBalanceUserService();
UserDto userDto= svr.getUser();
return "hi "+userDto.getUsername();
}
}//最后控制层实现数据获取


















spring boot 自动部署方案
现在主流的自动部署方案大都是基于Docker的了,但传统的自动部署方案比较适合中小型公司,下面的方案就是比较传统的自动部署方案
自动部署一般都是通过以下步骤进行的。
首选由持续性集成工具进行自动编译产生项目的输出,对于我们来说也就是 jar 包。
然后该 jar 经过测试就可以分发到各个服务器,各个服务器的监控脚本监控到该新版本
自动停止旧实例重新运行新实例。


详细版本:
Jenkins 编译的结果需要暂时存放,以便于测试人员拉取进行测试。这里存放在 maven 库中。
测试通过后也需要手动推送到生产环境,因为不可能每个版本都推送到生产环境。生产环境需要一
台 FTP 或 GIT、 SVN Server 作为中转机,暂存打包的应用,然后生产的服务器通过脚本轮询该中
转机获得新的版本。获得新的版本后,自动停止旧的版本,运行新的版本。










spring boot/cloud 应用监控
编写监控程序:cloud-monitor-server
pom.xml
<?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>cloud</groupId>
<artifactId>cloud-monitor-server</artifactId>
<version>1.0.0</version>
<name>cloud-monitor-server</name>
<packaging>jar</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.5.RELEASE</version>
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Brixton.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<repositories>
<repository>
<snapshots>
<enabled>true</enabled>
</snapshots>
<id>public</id>
<name>Public Repositories</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>public</id>
<name>Public Repositories</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
</pluginRepository>
</pluginRepositories>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.7</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-server</artifactId>
<version>1.3.3</version>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-server-ui</artifactId>
<version>1.3.3</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
<defaultGoal>compile</defaultGoal>
</build>
</project>
SpringBootAdminApplication
@Configuration
@EnableAutoConfiguration
@EnableDiscoveryClient
@EnableAdminServer
public class SpringBootAdminApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootAdminApplication.class, args);
}
}
application.properties
server.port=8050
spring.application.name=@pom.artifactId@
endpoints.health.sensitive=false
eureka.instance.leaseRenewalIntervalInSeconds=5
#指定了服务注册中心的位置
eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/
#在默认设置下,Eureka服务注册中心也会将自己作为客户端来尝试注册它自己,所以我们需要禁用它的客户端注册行为。
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
logback-spring.xml//当前日志级别管理仅限 Logback
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/logback/base.xml"/>
<jmxConfigurator/>
</configuration>




被监听程序需要先添加依赖
pom.xml
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
application.properties
spring.boot.admin.url=http://localhost:8050
#为了在 Spring Boot Admin 的应用管理列表显示被管理应用的版本号,你需要设置 info.version
info.version=@project.version@
ClientEurekaSampleApplication.java
@SpringBootApplication
//添加 @EnableDiscoveryClient 或 @EnableEurekaClient 注解到启动类上,将自己注册到 Erueka Server。
@EnableEurekaClient
public class ClientEurekaSampleApplication {
    public static void main(String[] args) {
        SpringApplication.run(ClientEurekaSampleApplication.class, args);
    }
}
logback.xml(与上者平级)
<configuration>
    <include resource="org/springframework/boot/logging/logback/base.xml"/>
    <jmxConfigurator/>
</configuration>
//https://blog.csdn.net/kinginblue/article/details/52132113可参考
























hystrix-turbine 监控的使用

查看全文
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

相关文章

  1. 桌面应用程序 azure_使用Azure静态Web应用程序服务构建Angular应用程序

    桌面应用程序 azureNowadays there are so many ways to build and deploy Angular apps such as angular with Java, Angular with Nodejs, serverless, etc. Building with Azure Static Web apps service is one of them and it is recently released by Microsoft Azure an…...

    2024/4/28 16:15:02
  2. Angular+SpringMVC+MongoDB集成单页面应用

    最近在学习Angular&#xff0c;所以就想用Angular做一个单页面应用&#xff0c;用了Nosql数据库mongodb,都是最近在学的&#xff0c;所以干脆写一个简单的增删改查&#xff0c;中间集成 的过程不是很顺利&#xff0c;特别是Angular和SpringMVC&#xff0c;所以在这里写出来&…...

    2024/4/21 4:20:35
  3. Spring Boot and OAuth2翻译

    Spring Boot and OAuth2 本指南将向您展示如何使用OAuth2和Spring Boot构建一个使用“社交登录”功能做各种事情的应用程序示例。 它从一个简单的单一提供者单点登录开始&#xff0c;并运行一个带有身份验证提供程序&#xff08;Facebook或Github&#xff09;的OAuth2自我托管…...

    2024/4/22 18:12:44
  4. spring ioc di 原理解析

    spring ioc原理&#xff08;看完后大家可以自己写一个spring&#xff09; 控制反转/依赖注入 其实这个Spring架构核心的概念没有这么复杂&#xff0c;更不像有些书上描述的那样晦涩。Java程序员都知道&#xff1a;java程序中的每个业务逻辑至少需要两个或以上的对象来协作完成&…...

    2024/4/21 4:20:33
  5. spring cloud微服务框架 第四天

    第四天&#xff0c;在之前的章节&#xff0c;我们已经实现了配置服务器、注册服务器、微服务服务端&#xff0c;实现了服务注册与发现。这一章将实现微服务的客户端&#xff0c;以及联调、实现整个spring cloud框架核心应用。 开源项目&#xff1a;http://git.oschina.net/zhou…...

    2024/4/21 4:20:32
  6. Spring依赖注入的三种方式(好的 坏的和丑的)

    关于spring bean三种注入方式的优缺点对比&#xff0c;翻译自Spring DI Patterns: The Good, The Bad, and The Ugly&#xff0c;水平有限&#xff0c;如有错误请指正。   Spring开发者会很熟悉spring强大的依赖注入API&#xff0c;这些API可以让你用Bean的注解让Spring实例化…...

    2024/5/8 19:42:56
  7. angular 初始化_应用程序初始化程序的工作原理,因此您需要了解有关angular中动态配置的知识...

    angular 初始化When we develop an application designed to run on multiple environments, we have to decide how to provide a configuration of appropriate variables depending on those environments当我们开发旨在在多种环境下运行的应用程序时&#xff0c;我们必须决…...

    2024/4/21 4:20:28
  8. Spring Security学习二 - 自定义Login方法

    Author: Kagula Date: 2016-9-19 环境 [1]Spring 3.1.2 [2]Tomcat 7.x 概要 在《Spring Security学习一》的基础上完善自定义Login界面&#xff0c;并增加了Login方法的自定义。 这里仅列出源码。 测试内容 [1]能否把密码明文转成密文,MD5加密。pass. [2]能否同S…...

    2024/4/21 4:20:26
  9. 使用Angular,Ionic 4和Spring Boot构建移动应用

    朋友不允许朋友写用户身份验证。 厌倦了管理自己的用户&#xff1f; 立即尝试Okta的API和Java SDK。 在几分钟之内即可对任何应用程序中的用户进行身份验证&#xff0c;管理和保护。 我是Ionic的忠实粉丝。 几年前&#xff0c;我基于AngularJS开始使用它。 作为开发人员&#…...

    2024/4/21 4:20:25
  10. SpringBoot入门系列:Spring Security 和 Angular JS(2)

    添加动态的内容 目前我们已经有了一个应用程序&#xff0c;硬编码了一句问候语在里面。这对学习如何把这些凑到一起很有帮助&#xff0c;不过实际上我们期望的是来自于后台服务器的内容&#xff0c;因此我们可以创建一个HTTP端点&#xff0c;然后用这个来抓取到一句问候语。在你…...

    2024/4/21 4:20:25
  11. Spring与Serverless 相关服务了解

    目录 前端开发模式的演进 Serverless 常见服务商提供的解决方案 基于 Serverless 的前端开发模式 serverless带来的价值 serverless实践 总结serverless - less is more Spring 对Serverless的实践 无服务器 什么是无服务器&#xff1f; 无服务器特性&#xff1f; 无…...

    2024/4/21 4:20:24
  12. Angular 架构概述

    Angular 8.1.0 环境搭建 & 初始化项目 两天学会Angular开发——第一天 两天学会Angular开发——第二天 架构概述 Angular应用的基本构建模块是 NgModules &#xff0c;它为组件提供编译上下文。Angular 应用程序由一组 NgModules 定义&#xff0c;至少有一个根模块&#…...

    2024/4/21 4:20:23
  13. Kotlin+Spring Boot开发REST API实战

    Kotlin简介 Kotlin是面向JVM、Android、JavaScript 及原生平台的开源静态类型编程语言&#xff0c;支持面向对象和函数式编程。Kotlin项目开始于2010年&#xff0c;由 JetBrains开发&#xff0c;2016年2月发布第一个官方版本1.0&#xff0c;当前版本是 1.3.72&#xff0c;发布…...

    2024/4/27 11:24:28
  14. 从零开始构建一个spring boot + angular web应用(1)

    http://www.jianshu.com/p/cd6f07e30443 首先&#xff0c;开始项目前&#xff0c;电脑的必备开发环境要首先具备。如&#xff0c; JDK、node、maven、bower等常用工具要具备。废话不多说了。 step 1 创建maven项目&#xff0c;随便找个地方创建一个文件夹demo&#xff0c;cmd进…...

    2024/4/21 4:20:21
  15. Spring 注解笔记整理

    Spring 注解整理 1.核心容器&#xff08;Core&#xff09; Spring Core 提供bean工厂 控制反转&#xff08;IOC&#xff09;&#xff0c;利用IOC使配置与代码进行分离&#xff0c;降低耦合。 基于xml配置元数据; Spring 2.5引入了基于注释的配置元数据; 从Spring 3开始基于ja…...

    2024/4/21 4:20:20
  16. Angular的后院:组件依赖关系的解决

    by Dor Moshe通过Dor Moshe Angular的后院&#xff1a;解决 组件依赖关系 (Angular’s Backyard: The Resolving of Components Dependencies) This article originally appeared on dormoshe.io这篇文章 最初出现在dormoshe.io Many of us use the Hierarchical Dependenc…...

    2024/4/21 4:20:19
  17. Spring Boot 学习笔记

    嗯,加油生活,依旧,摘几句子.我十有八九的欲言又止&#xff0c;在日后想来都庆幸。而绝大多数的敞开心扉在事后都追悔。 -------德卡先生的信箱2019.10.3 Spring的发展 Spring1.x 时代&#xff1a;在Spring1.x时代&#xff0c;都是通过xml文件配置bean&#xff0c;随着项目的…...

    2024/4/20 19:51:01
  18. Application of LiDAR in driveless technology

    电子科技大学格拉斯哥学院 2017级 贺俊皓 The car accident happened in Chongqing last month is really a tragedy for all peopel in China.The unreasonalbe female passenger was accused of the crime culprit of this accident. So, which kind of measure could be ada…...

    2024/4/20 16:21:01
  19. paper survey ——Underwater optical communication

    本博文为本人阅读水下通信系列的笔记 Gaussian kernel-aided deep neural network equalizer utilized in underwater PAM8 visible light communication system VLC has advantages that include high speed, the absence of electromagnetic radiation, safety for human ey…...

    2024/4/23 22:51:33
  20. 把这304道React的面试题刷完,前端面试没有在怕的!

    Core React 什么是 React? React 是一个开源前端 JavaScript 库&#xff0c;用于构建用户界面&#xff0c;尤其是单页应用程序。它用于处理网页和移动应用程序的视图层。React 是由 Facebook 的软件工程师 Jordan Walke 创建的。在 2011 年 React 应用首次被部署到 Facebook 的…...

    2024/4/29 3:55:16

最新文章

  1. 【日志革新】在ThinkPHP5中实现高效TraceId集成,打造可靠的日志追踪系统

    问题背景 最近接手了一个骨灰级的项目&#xff0c;然而在项目中遇到了一个普遍的挑战&#xff1a;由于公司采用 ELK&#xff08;Elasticsearch、Logstash、Kibana&#xff09;作为日志收集和分析工具&#xff0c;追踪生产问题成为了一大难题。尽管 ELK 提供了强大的日志分析功…...

    2024/5/8 20:12:06
  2. 梯度消失和梯度爆炸的一些处理方法

    在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言&#xff0c;在此感激不尽。 权重和梯度的更新公式如下&#xff1a; w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...

    2024/5/7 10:36:02
  3. 【opencv】示例-epipolar_lines.cpp 对极线

    这段代码总的功能是使用OpenCV库进行立体视觉的估计。它从命令行读取两个图像文件名&#xff0c;使用SIFT算法检测关键点并计算这些点的描述子&#xff0c;接着通过FLANN库进行快速近似最近邻搜索来找到匹配的关键点。然后使用RANSAC方法计算基础矩阵&#xff0c;找到内点&…...

    2024/5/6 21:58:46
  4. 第十三届蓝桥杯大赛软件赛省赛C/C++ 大学 B 组 题解

    VP比赛链接 : 数据加载中... - 蓝桥云课 1 . 九进制 转 十进制 直接模拟就好了 #include <iostream> using namespace std; int main() {// 请在此输入您的代码int x 22*92*81*9;cout << x << endl ;return 0; } 2 . 顺子日期 枚举出每个情况即可 : …...

    2024/5/6 13:50:47
  5. Java中的装饰器模式

    在Java中&#xff0c;装饰器模式允许我们动态地给对象添加新的行为或责任&#xff0c;而无需修改原有类。以下是一个简单的装饰器模式示例&#xff0c;我们将模拟一个咖啡销售系统&#xff0c;其中基础饮料类&#xff08;Component&#xff09;是Coffee&#xff0c;装饰器类&am…...

    2024/5/7 6:32:52
  6. 【外汇早评】美通胀数据走低,美元调整

    原标题:【外汇早评】美通胀数据走低,美元调整昨日美国方面公布了新一期的核心PCE物价指数数据,同比增长1.6%,低于前值和预期值的1.7%,距离美联储的通胀目标2%继续走低,通胀压力较低,且此前美国一季度GDP初值中的消费部分下滑明显,因此市场对美联储后续更可能降息的政策…...

    2024/5/8 6:01:22
  7. 【原油贵金属周评】原油多头拥挤,价格调整

    原标题:【原油贵金属周评】原油多头拥挤,价格调整本周国际劳动节,我们喜迎四天假期,但是整个金融市场确实流动性充沛,大事频发,各个商品波动剧烈。美国方面,在本周四凌晨公布5月份的利率决议和新闻发布会,维持联邦基金利率在2.25%-2.50%不变,符合市场预期。同时美联储…...

    2024/5/7 9:45:25
  8. 【外汇周评】靓丽非农不及疲软通胀影响

    原标题:【外汇周评】靓丽非农不及疲软通胀影响在刚结束的周五,美国方面公布了新一期的非农就业数据,大幅好于前值和预期,新增就业重新回到20万以上。具体数据: 美国4月非农就业人口变动 26.3万人,预期 19万人,前值 19.6万人。 美国4月失业率 3.6%,预期 3.8%,前值 3…...

    2024/5/4 23:54:56
  9. 【原油贵金属早评】库存继续增加,油价收跌

    原标题:【原油贵金属早评】库存继续增加,油价收跌周三清晨公布美国当周API原油库存数据,上周原油库存增加281万桶至4.692亿桶,增幅超过预期的74.4万桶。且有消息人士称,沙特阿美据悉将于6月向亚洲炼油厂额外出售更多原油,印度炼油商预计将每日获得至多20万桶的额外原油供…...

    2024/5/7 14:25:14
  10. 【外汇早评】日本央行会议纪要不改日元强势

    原标题:【外汇早评】日本央行会议纪要不改日元强势近两日日元大幅走强与近期市场风险情绪上升,避险资金回流日元有关,也与前一段时间的美日贸易谈判给日本缓冲期,日本方面对汇率问题也避免继续贬值有关。虽然今日早间日本央行公布的利率会议纪要仍然是支持宽松政策,但这符…...

    2024/5/4 23:54:56
  11. 【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响

    原标题:【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响近日伊朗局势升温,导致市场担忧影响原油供给,油价试图反弹。此时OPEC表态稳定市场。据消息人士透露,沙特6月石油出口料将低于700万桶/日,沙特已经收到石油消费国提出的6月份扩大出口的“适度要求”,沙特将满…...

    2024/5/4 23:55:05
  12. 【外汇早评】美欲与伊朗重谈协议

    原标题:【外汇早评】美欲与伊朗重谈协议美国对伊朗的制裁遭到伊朗的抗议,昨日伊朗方面提出将部分退出伊核协议。而此行为又遭到欧洲方面对伊朗的谴责和警告,伊朗外长昨日回应称,欧洲国家履行它们的义务,伊核协议就能保证存续。据传闻伊朗的导弹已经对准了以色列和美国的航…...

    2024/5/4 23:54:56
  13. 【原油贵金属早评】波动率飙升,市场情绪动荡

    原标题:【原油贵金属早评】波动率飙升,市场情绪动荡因中美贸易谈判不安情绪影响,金融市场各资产品种出现明显的波动。随着美国与中方开启第十一轮谈判之际,美国按照既定计划向中国2000亿商品征收25%的关税,市场情绪有所平复,已经开始接受这一事实。虽然波动率-恐慌指数VI…...

    2024/5/7 11:36:39
  14. 【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试

    原标题:【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试美国和伊朗的局势继续升温,市场风险情绪上升,避险黄金有向上突破阻力的迹象。原油方面稍显平稳,近期美国和OPEC加大供给及市场需求回落的影响,伊朗局势并未推升油价走强。近期中美贸易谈判摩擦再度升级,美国对中…...

    2024/5/4 23:54:56
  15. 【原油贵金属早评】市场情绪继续恶化,黄金上破

    原标题:【原油贵金属早评】市场情绪继续恶化,黄金上破周初中国针对于美国加征关税的进行的反制措施引发市场情绪的大幅波动,人民币汇率出现大幅的贬值动能,金融市场受到非常明显的冲击。尤其是波动率起来之后,对于股市的表现尤其不安。隔夜美国股市出现明显的下行走势,这…...

    2024/5/6 1:40:42
  16. 【外汇早评】美伊僵持,风险情绪继续升温

    原标题:【外汇早评】美伊僵持,风险情绪继续升温昨日沙特两艘油轮再次发生爆炸事件,导致波斯湾局势进一步恶化,市场担忧美伊可能会出现摩擦生火,避险品种获得支撑,黄金和日元大幅走强。美指受中美贸易问题影响而在低位震荡。继5月12日,四艘商船在阿联酋领海附近的阿曼湾、…...

    2024/5/4 23:54:56
  17. 【原油贵金属早评】贸易冲突导致需求低迷,油价弱势

    原标题:【原油贵金属早评】贸易冲突导致需求低迷,油价弱势近日虽然伊朗局势升温,中东地区几起油船被袭击事件影响,但油价并未走高,而是出于调整结构中。由于市场预期局势失控的可能性较低,而中美贸易问题导致的全球经济衰退风险更大,需求会持续低迷,因此油价调整压力较…...

    2024/5/4 23:55:17
  18. 氧生福地 玩美北湖(上)——为时光守候两千年

    原标题:氧生福地 玩美北湖(上)——为时光守候两千年一次说走就走的旅行,只有一张高铁票的距离~ 所以,湖南郴州,我来了~ 从广州南站出发,一个半小时就到达郴州西站了。在动车上,同时改票的南风兄和我居然被分到了一个车厢,所以一路非常愉快地聊了过来。 挺好,最起…...

    2024/5/7 9:26:26
  19. 氧生福地 玩美北湖(中)——永春梯田里的美与鲜

    原标题:氧生福地 玩美北湖(中)——永春梯田里的美与鲜一觉醒来,因为大家太爱“美”照,在柳毅山庄去寻找龙女而错过了早餐时间。近十点,向导坏坏还是带着饥肠辘辘的我们去吃郴州最富有盛名的“鱼头粉”。说这是“十二分推荐”,到郴州必吃的美食之一。 哇塞!那个味美香甜…...

    2024/5/4 23:54:56
  20. 氧生福地 玩美北湖(下)——奔跑吧骚年!

    原标题:氧生福地 玩美北湖(下)——奔跑吧骚年!让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 啊……啊……啊 两…...

    2024/5/8 19:33:07
  21. 扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!

    原标题:扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!扒开伪装医用面膜,翻六倍价格宰客!当行业里的某一品项火爆了,就会有很多商家蹭热度,装逼忽悠,最近火爆朋友圈的医用面膜,被沾上了污点,到底怎么回事呢? “比普通面膜安全、效果好!痘痘、痘印、敏感肌都能用…...

    2024/5/5 8:13:33
  22. 「发现」铁皮石斛仙草之神奇功效用于医用面膜

    原标题:「发现」铁皮石斛仙草之神奇功效用于医用面膜丽彦妆铁皮石斛医用面膜|石斛多糖无菌修护补水贴19大优势: 1、铁皮石斛:自唐宋以来,一直被列为皇室贡品,铁皮石斛生于海拔1600米的悬崖峭壁之上,繁殖力差,产量极低,所以古代仅供皇室、贵族享用 2、铁皮石斛自古民间…...

    2024/5/4 23:55:16
  23. 丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者

    原标题:丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者【公司简介】 广州华彬企业隶属香港华彬集团有限公司,专注美业21年,其旗下品牌: 「圣茵美」私密荷尔蒙抗衰,产后修复 「圣仪轩」私密荷尔蒙抗衰,产后修复 「花茵莳」私密荷尔蒙抗衰,产后修复 「丽彦妆」专注医学护…...

    2024/5/4 23:54:58
  24. 广州械字号面膜生产厂家OEM/ODM4项须知!

    原标题:广州械字号面膜生产厂家OEM/ODM4项须知!广州械字号面膜生产厂家OEM/ODM流程及注意事项解读: 械字号医用面膜,其实在我国并没有严格的定义,通常我们说的医美面膜指的应该是一种「医用敷料」,也就是说,医用面膜其实算作「医疗器械」的一种,又称「医用冷敷贴」。 …...

    2024/5/6 21:42:42
  25. 械字号医用眼膜缓解用眼过度到底有无作用?

    原标题:械字号医用眼膜缓解用眼过度到底有无作用?医用眼膜/械字号眼膜/医用冷敷眼贴 凝胶层为亲水高分子材料,含70%以上的水分。体表皮肤温度传导到本产品的凝胶层,热量被凝胶内水分子吸收,通过水分的蒸发带走大量的热量,可迅速地降低体表皮肤局部温度,减轻局部皮肤的灼…...

    2024/5/4 23:54:56
  26. 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...

    解析如下&#xff1a;1、长按电脑电源键直至关机&#xff0c;然后再按一次电源健重启电脑&#xff0c;按F8健进入安全模式2、安全模式下进入Windows系统桌面后&#xff0c;按住“winR”打开运行窗口&#xff0c;输入“services.msc”打开服务设置3、在服务界面&#xff0c;选中…...

    2022/11/19 21:17:18
  27. 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。

    %读入6幅图像&#xff08;每一幅图像的大小是564*564&#xff09; f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...

    2022/11/19 21:17:16
  28. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...

    win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面&#xff0c;在等待界面中我们需要等待操作结束才能关机&#xff0c;虽然这比较麻烦&#xff0c;但是对系统进行配置和升级…...

    2022/11/19 21:17:15
  29. 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...

    有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows&#xff0c;请勿关闭计算机”的提示&#xff0c;要过很久才能进入系统&#xff0c;有的用户甚至几个小时也无法进入&#xff0c;下面就教大家这个问题的解决方法。第一种方法&#xff1a;我们首先在左下角的“开始…...

    2022/11/19 21:17:14
  30. win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...

    置信有很多用户都跟小编一样遇到过这样的问题&#xff0c;电脑时发现开机屏幕显现“正在配置Windows Update&#xff0c;请勿关机”(如下图所示)&#xff0c;而且还需求等大约5分钟才干进入系统。这是怎样回事呢&#xff1f;一切都是正常操作的&#xff0c;为什么开时机呈现“正…...

    2022/11/19 21:17:13
  31. 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...

    Win7系统开机启动时总是出现“配置Windows请勿关机”的提示&#xff0c;没过几秒后电脑自动重启&#xff0c;每次开机都这样无法进入系统&#xff0c;此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一&#xff1a;开机按下F8&#xff0c;在出现的Windows高级启动选…...

    2022/11/19 21:17:12
  32. 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...

    有不少windows10系统用户反映说碰到这样一个情况&#xff0c;就是电脑提示正在准备windows请勿关闭计算机&#xff0c;碰到这样的问题该怎么解决呢&#xff0c;现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法&#xff1a;1、2、依次…...

    2022/11/19 21:17:11
  33. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...

    今天和大家分享一下win7系统重装了Win7旗舰版系统后&#xff0c;每次关机的时候桌面上都会显示一个“配置Windows Update的界面&#xff0c;提示请勿关闭计算机”&#xff0c;每次停留好几分钟才能正常关机&#xff0c;导致什么情况引起的呢&#xff1f;出现配置Windows Update…...

    2022/11/19 21:17:10
  34. 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...

    只能是等着&#xff0c;别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚&#xff0c;只能是考虑备份数据后重装系统了。解决来方案一&#xff1a;管理员运行cmd&#xff1a;net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...

    2022/11/19 21:17:09
  35. 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?

    原标题&#xff1a;电脑提示“配置Windows Update请勿关闭计算机”怎么办&#xff1f;win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢&#xff1f;一般的方…...

    2022/11/19 21:17:08
  36. 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...

    关机提示 windows7 正在配置windows 请勿关闭计算机 &#xff0c;然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;关机提示 windows7 正在配…...

    2022/11/19 21:17:05
  37. 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...

    钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...

    2022/11/19 21:17:05
  38. 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...

    前几天班里有位学生电脑(windows 7系统)出问题了&#xff0c;具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面&#xff0c;长时间没反应&#xff0c;无法进入系统。这个问题原来帮其他同学也解决过&#xff0c;网上搜了不少资料&#x…...

    2022/11/19 21:17:04
  39. 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...

    本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法&#xff0c;并在最后教给你1种保护系统安全的好方法&#xff0c;一起来看看&#xff01;电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中&#xff0c;添加了1个新功能在“磁…...

    2022/11/19 21:17:03
  40. 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...

    许多用户在长期不使用电脑的时候&#xff0c;开启电脑发现电脑显示&#xff1a;配置windows更新失败&#xff0c;正在还原更改&#xff0c;请勿关闭计算机。。.这要怎么办呢&#xff1f;下面小编就带着大家一起看看吧&#xff01;如果能够正常进入系统&#xff0c;建议您暂时移…...

    2022/11/19 21:17:02
  41. 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...

    配置windows update失败 还原更改 请勿关闭计算机&#xff0c;电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;配置windows update失败 还原更改 请勿关闭计算机&#x…...

    2022/11/19 21:17:01
  42. 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...

    不知道大家有没有遇到过这样的一个问题&#xff0c;就是我们的win7系统在关机的时候&#xff0c;总是喜欢显示“准备配置windows&#xff0c;请勿关机”这样的一个页面&#xff0c;没有什么大碍&#xff0c;但是如果一直等着的话就要两个小时甚至更久都关不了机&#xff0c;非常…...

    2022/11/19 21:17:00
  43. 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...

    当电脑出现正在准备配置windows请勿关闭计算机时&#xff0c;一般是您正对windows进行升级&#xff0c;但是这个要是长时间没有反应&#xff0c;我们不能再傻等下去了。可能是电脑出了别的问题了&#xff0c;来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...

    2022/11/19 21:16:59
  44. 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...

    我们使用电脑的过程中有时会遇到这种情况&#xff0c;当我们打开电脑之后&#xff0c;发现一直停留在一个界面&#xff1a;“配置Windows Update失败&#xff0c;还原更改请勿关闭计算机”&#xff0c;等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢&#xff0…...

    2022/11/19 21:16:58
  45. 如何在iPhone上关闭“请勿打扰”

    Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...

    2022/11/19 21:16:57