折腾了好久,在网上找倒以下几种解决办法:
1、使用管理员模式来运行Impactor
2、使用impactor的revoke certificates清除证书后尝试
3、关闭appleid的双重验证
4、使用新的appleid
以上说的,第二种apple已经不允许关闭了,第三种是不现实的,所以我使用第一种和第二种都死活不成功。
原来,使用impactor的revoke certificates清除证书后,需要先重启你的iphone,然后再重签,否则死活不成功。
折腾了好久,在网上找倒以下几种解决办法:
1、使用管理员模式来运行Impactor
2、使用impactor的revoke certificates清除证书后尝试
3、关闭appleid的双重验证
4、使用新的appleid
以上说的,第二种apple已经不允许关闭了,第三种是不现实的,所以我使用第一种和第二种都死活不成功。
原来,使用impactor的revoke certificates清除证书后,需要先重启你的iphone,然后再重签,否则死活不成功。
有时候在myeclipse或者eclipse中打开properties文件时会发现其中的中文都是乱码。这是由于当前的properties文件编码格式不支持汉字造成的。当这种情况发生时,我们可以按照以下两种方式更改文件的编码格式即可。方法一可以一次性更改所有项目的properties文件编码格式。方法二可以根据需要有选择地对某些文件进行更改。
方法一:依次点击windows-preferences-content-text-Java properties file,并将弹出窗和右下方的default encoding该为GBK,然后依次点击update-OK关闭弹出窗格即可。另外,在次窗口中,如果在右侧上方窗格内选择其他文件类型,则可以对其他文件的编码进行全局更改。
方法二:右击某个需要更改的properties文件,选择properties,在弹出窗的左侧树状目录上选择Resource,右下方的text file encoding编辑区内点击other,然后选择GBK(如果没有,可直接手动输入),最后依次点击apply-ok关闭弹出窗口即可。
1、首先到https://start.spring.io/中创建版本为2.1.x项目,在本地的IDEA导入后,首先在pom.xml中增加以下依赖(在pom.xml的<dependencies></dependencies>之间):
<!--Netflix Eureka依赖--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency>
2、然后在pom.xml的<project></project>之间增加以下关于springcloud的版本管理:
<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>
3、接着在在pom.xml的<properties></properties>中增加以下配置(注意:Greenwich对应的是springboot2.1.x版本,如果换成其他的会报错,就这个坑把我坑了一个下午):
<spring-cloud.version>Greenwich.SR3</spring-cloud.version>
4、还有在application.properties中增加如下配置:
1)eureka服务器是这样配置的:
server.port=8761 spring.application.name=eureka-server-1 #注册的域名(注意:可以使用localhost,但在高可用时,不同的eureka-server必须要使用不同的hostname,否则无法相互发现) eureka.instance.hostname=eureka-server-1 #是否向注册中心注册自己(非高可用时为false,高可用时为true) eureka.client.registerWithEureka=true #是否从eureka上获取信息(非高可用时为false,高可用时为true) eureka.client.fetchRegistry=true #eureka通信地址(非高可用时写自己的eureka-server地址,高可用时填高可用的目标eureka-server地址) eureka.client.serviceUrl.defaultZone=http\://eureka-server-2\:8762/eureka/
2)eureka服务提供者是这样配置的:
server.port=8771 spring.application.name=client1 eureka.instance.prefer-ip-address=true #多个eureka-server时可用","号分隔 eureka.client.serviceUrl.defaultZone=http\://localhost\:8761/eureka/
5、最后在springboot的启动文件xxxApplication.java中增加对应的注解:
1)eureka服务器要使用@EnableEurekaServer注解:
package com.zero4j.eurekaserver; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; @EnableEurekaServer @SpringBootApplication public class EurekaServerApplication { public static void main(String[] args) { SpringApplication.run(EurekaServerApplication.class, args); } }
2)eureka服务器要使用@EurekaClient1Application注解:
package com.zero4j.eurekaclient1; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; @SpringBootApplication @EnableDiscoveryClient //也可以用EnableDiscoveryClient代替,前者兼容性更大,后者仅能兼容Eureka public class EurekaClient1Application { public static void main(String[] args) { SpringApplication.run(EurekaClient1Application.class, args); } }
访问eureka-server对应的端口,将会显示以下是最终的运行结果:
1、首先到https://start.spring.io/中创建版本为2.1.x项目,在本地的IDEA导入后,首先在pom.xml中增加以下依赖(在pom.xml的<dependencies></dependencies>之间):
<!--Netflix Eureka依赖--> <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-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-ribbon</artifactId> </dependency>
2、然后在pom.xml的<project></project>之间增加以下关于springcloud的版本管理:
<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>
3、接着在在pom.xml的<properties></properties>中增加以下配置(注意:Greenwich对应的是springboot2.1.x版本,如果换成其他的会报错,就这个坑把我坑了一个下午):
<spring-cloud.version>Greenwich.SR3</spring-cloud.version>
4、还有在application.properties中增加如下配置:
#消费者端口 server.port=8081 spring.application.name=eureka-consumer-1 eureka.instance.hostname=localhost eureka.client.service-url.defaultZone=http\://localhost\:8761/eureka/,http\://localhost\:8762/eureka/
5、创建RestTemplate模板配置
package com.zero4j.config; import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.client.RestTemplate; @Configuration public class RestTemplateConfig { /** * RestTemplate:提供了多种便捷访问远程Http服务的方法 * 是一种简单便捷访问Restful服务模板类,提供用于访问Rest服务的客户端模板类 */ @Bean @LoadBalanced public RestTemplate restTemplate(){ return new RestTemplate(); } }
6、消费者调用eureka服务示例
package com.zero4j.controller; import java.util.Random; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate; @RestController @RequestMapping("/") public class TestControllerProvider { @Autowired private RestTemplate restTemplate; @GetMapping("/test") public String test() { //通过服务提供者名称调用 //List<Dept> depts = restTemplate.getForObject("http://wzx-spring-cloud-provider/dept/findAll", List.class); //return depts; String test = restTemplate.getForObject("http://eureka-client-1/test", String.class); return test; } }
7、服务提供者的java示例
package com.zero4j.controller; import java.util.Random; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/") public class TestControllerProvider { @GetMapping("/test") public String test() { return "服务提供者1:"+String.valueOf((new Random()).nextInt()); } }
增加以下两个配置文件:
TransactionAdviceConfig.java
package com.zero4j.config; import org.aspectj.lang.annotation.Aspect; import org.springframework.aop.Advisor; import org.springframework.aop.aspectj.AspectJExpressionPointcut; import org.springframework.aop.support.DefaultPointcutAdvisor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.interceptor.DefaultTransactionAttribute; import org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource; import org.springframework.transaction.interceptor.TransactionInterceptor; @Aspect @Configuration public class TransactionAdviceConfig { //使dao使用session private static final String AOP_POINTCUT_EXPRESSION = " (execution(* com..dao..*.*(..))) "; //controller由过滤器中进行设置,这里设置会抽风 /*private static final String AOP_POINTCUT_EXPRESSION2 = " (execution(* com..controller..*.*(..))) ";*/ @Autowired private PlatformTransactionManager transactionManager; @Bean public TransactionInterceptor txAdvice() { DefaultTransactionAttribute txAttr_REQUIRED = new DefaultTransactionAttribute(); txAttr_REQUIRED.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); DefaultTransactionAttribute txAttr_REQUIRED_READONLY = new DefaultTransactionAttribute(); txAttr_REQUIRED_READONLY.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); txAttr_REQUIRED_READONLY.setReadOnly(true); DefaultTransactionAttribute txAttr_READONLY = new DefaultTransactionAttribute(); txAttr_READONLY.setReadOnly(true); NameMatchTransactionAttributeSource source = new NameMatchTransactionAttributeSource(); source.addTransactionalMethod("save*", txAttr_REQUIRED); source.addTransactionalMethod("add*", txAttr_REQUIRED); source.addTransactionalMethod("create*", txAttr_REQUIRED); source.addTransactionalMethod("insert*", txAttr_REQUIRED); source.addTransactionalMethod("update*", txAttr_REQUIRED); source.addTransactionalMethod("merge*", txAttr_REQUIRED); source.addTransactionalMethod("del*", txAttr_REQUIRED); source.addTransactionalMethod("remove*", txAttr_REQUIRED); source.addTransactionalMethod("put*", txAttr_REQUIRED); source.addTransactionalMethod("use*", txAttr_REQUIRED); source.addTransactionalMethod("exec*", txAttr_REQUIRED); source.addTransactionalMethod("set*", txAttr_REQUIRED); source.addTransactionalMethod("get*", txAttr_REQUIRED_READONLY);//特殊,service在save后会重新读取,如果设置成REQUIRED_READONLY,则save不会保存数据 source.addTransactionalMethod("count*", txAttr_REQUIRED_READONLY); source.addTransactionalMethod("find*", txAttr_REQUIRED_READONLY); source.addTransactionalMethod("list*", txAttr_REQUIRED_READONLY); source.addTransactionalMethod("query*", txAttr_REQUIRED_READONLY); source.addTransactionalMethod("find*", txAttr_REQUIRED_READONLY); source.addTransactionalMethod("is*", txAttr_REQUIRED_READONLY); /* source.addTransactionalMethod("save*", txAttr_REQUIRED); source.addTransactionalMethod("delete*", txAttr_REQUIRED); source.addTransactionalMethod("update*", txAttr_REQUIRED); source.addTransactionalMethod("exec*", txAttr_REQUIRED); source.addTransactionalMethod("set*", txAttr_REQUIRED); source.addTransactionalMethod("get*", txAttr_REQUIRED_READONLY); source.addTransactionalMethod("query*", txAttr_REQUIRED_READONLY); source.addTransactionalMethod("find*", txAttr_REQUIRED_READONLY); source.addTransactionalMethod("list*", txAttr_REQUIRED_READONLY); source.addTransactionalMethod("count*", txAttr_REQUIRED_READONLY); source.addTransactionalMethod("is*", txAttr_REQUIRED_READONLY); */ source.addTransactionalMethod("*", txAttr_READONLY); return new TransactionInterceptor(transactionManager, source); } @Bean public Advisor txAdviceAdvisor() { AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut(); pointcut.setExpression( AOP_POINTCUT_EXPRESSION ); return new DefaultPointcutAdvisor(pointcut, txAdvice()); } /* @Bean public Advisor txAdviceAdvisor2() { AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut(); pointcut.setExpression( AOP_POINTCUT_EXPRESSION2 ); return new DefaultPointcutAdvisor(pointcut, txAdvice()); }*/ }
FilterConfig.java
package com.zero4j.config; import org.aspectj.lang.annotation.Aspect; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.orm.hibernate5.support.OpenSessionInViewFilter; @Aspect @Configuration public class FilterConfig { //解决调用接口时session抽风的问题 @Bean public FilterRegistrationBean<OpenSessionInViewFilter> testFilterRegistration() { FilterRegistrationBean<OpenSessionInViewFilter> registration = new FilterRegistrationBean<>(); registration.setFilter(new OpenSessionInViewFilter()); registration.addUrlPatterns("/*");//配置过滤路径 return registration; } }
使用以下命令进行安装:
yum install vsftpd
安装完毕后,使用以下命令启动服务:
systemctl start vsftpd systemctl status vsftpd
并查看服务的启动状态:
如需要设置开机启动,则使用以下命令:
systemctl enable vsftpd
使用 vi /etc/vsftpd/vsftpd.conf 编辑配置,确保以下三项为YES:
anonymous_enable=YES
anon_upload_enable=YES
anon_mkdir_write_enable=YES
保存后使用以下命令重启vsftp从而让配置生效:
systemctl restart vsftpd
使用以下命令安装ftp工具
yum install ftp
安装后使用anonymous匿名用户登录(无需登录密码)
ftp localhost
如图所示:
220表示服务正常,可以登陆;230表示登陆成功。
在ftp工具内使用ls命令可以查看文件夹信息:
直接在浏览器中输入”ftp://ip/”后,使用匿名用户登录看是否正常:
建议使用cuteFtp工具进行连接,这样在连接使用时内看到错误信息
使用 vi /etc/vsftpd/vsftpd.conf 修改vsftp的配置:
anonymous_enable=YES 改为 NO(意思是禁止匿名用户登录)
#是否允许匿名用户登录(默认为YES) anonymous_enable=NO
将下图两行代码前的#号去掉,代表对chroot_list文件内的用户进行限制
#是否对chroot_list文件内的用户进行限制(默认为NO) chroot_list_enable=YES # (default follows) chroot_list_file=/etc/vsftpd/chroot_list
在文件最后面新增 allow_writeable_chroot=YES,表示允许已登录用户进行上传
#是否已登录用户进行上传(默认无此配置) allow_writeable_chroot=YES
使用以下命令创建不允许进行shell登录的ftp用户:
useradd -d /home/ftptest -s /sbin/nologin ftptest
然后使用以下命令将刚刚创建的用户放在ftp用户组中:
usermod -aG ftp ftptest
分配目录操作权限给刚刚创建的ftp用户:
chown ftptest /home/ftptest
使用以下命令修改刚刚创建的ftp用户密码:
passwd ftptest
使用“vi /etc/vsftpd/chroot_list”命令修改用户登录名单:
然后使用ftp工具进行连接测试。
如果遇到密码明明正确但是始终提示503密码错误的情况,可修改“vi /etc/pam.d/vsftpd”文件,注释掉:
#auth required pam_shells.so
然后重启vsftp:
systemctl restart vsftpd
编辑 /etc/vsftpd/vsftpd.conf 配置文件,在最下面添加以下信息:
#以下配置是为了解决连接超时的问题 #开启被动模式(默认无此配置) pasv_enable=YES pasv_min_port=4000 #随机最小端口 pasv_max_port=5000 #随机最大端口 #关闭DNS反向解析(默认无此配置) reverse_lookup_enable=NO
以上代码实现两个功能:
然后重启vsftp:
systemctl restart vsftpd
1、引入pom依赖包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
2、配置application.application
# spring session使用存储类型
spring.session.store-type=redis
#配置redis集群
spring.redis.cluster.nodes=192.168.1.55:7000,192.168.1.53:7003
3、启动类中增加@EnableRedisHttpSession
4、使用
request.getSession().setAttribute(“username”, “admin”);
String userName = (String) request.getSession().getAttribute(“username”);
在pom.xml加入:
<!-- 对Redis的支持 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
增加配置文件RedisConfig.java:
package com.zero4j.config; import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.cache.CacheManager; import org.springframework.cache.annotation.CachingConfigurerSupport; import org.springframework.cache.annotation.EnableCaching; import org.springframework.cache.interceptor.KeyGenerator; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.cache.RedisCacheManager; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; import java.lang.reflect.Method; /** * Redis 缓存配置类(通用) * @author linhongcun * */ @Configuration @EnableCaching public class RedisConfig extends CachingConfigurerSupport { /** * 缓存对象集合中,缓存是以 key-value 形式保存的。当不指定缓存的 key 时,SpringBoot 会使用 SimpleKeyGenerator 生成 key。 * @return */ @Bean public KeyGenerator wiselyKeyGenerator() { return new KeyGenerator() { @Override public Object generate(Object target, Method method, Object... params) { StringBuilder sb = new StringBuilder(); sb.append(target.getClass().getName()); sb.append(method.getName()); for (Object obj : params) { sb.append(obj.toString()); } return sb.toString(); } }; } @Bean public CacheManager cacheManager(RedisConnectionFactory factory) { return RedisCacheManager.create(factory); } @Bean public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) { StringRedisTemplate template = new StringRedisTemplate(factory); @SuppressWarnings({ "rawtypes", "unchecked" }) Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); ObjectMapper om = new ObjectMapper(); om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); jackson2JsonRedisSerializer.setObjectMapper(om); template.setValueSerializer(jackson2JsonRedisSerializer); template.afterPropertiesSet(); return template; } }
在application.properties中加入:
# Redis spring.redis.host=127.0.0.1 spring.redis.port=6379
对Service类加入注解@CacheConfig和@Cacheable,如:
package com.zero4j.model.config; import java.util.List; import org.springframework.cache.annotation.CacheConfig; import org.springframework.cache.annotation.Cacheable; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.stereotype.Repository; @Repository @CacheConfig(cacheNames = "configRepository") public interface ConfigRepository extends JpaRepository<Config, String> { @Query("SELECT config FROM Config config") @Cacheable(value = "findAll",keyGenerator="wiselyKeyGenerator") List<Config> findAll(); }
测试环境服务器参数:
CPU:4核8G带宽200M
RDS:1核1G
操作系统:Linux
JDK版本:1.8
WEB容器:Tomcat 8
压测工具:JMeter 3.2
每个组合分别的test内容基本如下(根据搭配的数据库不同,有些方法命名稍有差异):
@Controller @RequestMapping("") public class RootController { @Autowired private UserService userService; @RequestMapping(value={"","/","/index"}) String view(Map<String, Object> map){ System.out.println("首页(default)"); map.put("name", "SpringBoot"); map.put("date", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); return "index.jsp"; } @RequestMapping(value={"test1"}) @ResponseBody String test() { String str = "(new Random()).nextInt() = "+(new Random()).nextInt(); System.out.println(str); return str; } @RequestMapping(value="test2") public void test2(HttpServletRequest request, HttpServletResponse response) { String str = "(new Random()).nextInt() = "+(new Random()).nextInt(); System.out.println(str); ResponseStaticUtil.write(response, str); } @RequestMapping(value={"get1"}) @ResponseBody String get1() { User user = this.userService.get(1); String str = "user = "+user.getName()+" / (new Random()).nextInt() = "+(new Random()).nextInt(); System.out.println(str); return str; } @RequestMapping(value="get2") public void get2(HttpServletRequest request, HttpServletResponse response) { User user = this.userService.get(1); String str = "user = "+user.getName()+" / (new Random()).nextInt() = "+(new Random()).nextInt(); System.out.println(str); ResponseStaticUtil.write(response, str); } @RequestMapping(value={"list1"}) @ResponseBody String list() { List<User> users = this.userService.listAll(); String str = "users.size()= "+users.size()+" / (new Random()).nextInt() = "+(new Random()).nextInt(); System.out.println(str); return str; } @RequestMapping(value="list2") public void list2(HttpServletRequest request, HttpServletResponse response) { List<User> users = this.userService.listAll(); String str = "users.size()= "+users.size()+" / (new Random()).nextInt() = "+(new Random()).nextInt(); System.out.println(str); ResponseStaticUtil.write(response, str); } }
普通SpringMVC+Hibernate项目的各Controller压力测试结果:
SpringBoot+MyBatis项目的各Controller压力测试结果:
SpringBoot+JPA项目的各Controller压力测试结果:
SpringBoot+Hibernate项目的各Controller压力测试结果:
” SpringBoot+MyBatis / SpringBoot+JPA / SpringBoot+Hibernate ” 的get单个user对象压力测试对比:
” SpringBoot+MyBatis / SpringBoot+JPA / SpringBoot+Hibernate ” 的获取user所有对象(只有3个数据)压力测试对比:
总结:
1、在写Controller方法时,普通SpringMVC框架在使用普通的response.write的方式时效率很高,但使用annotation的方式返回数据时效率十分低;反之,使用SpringBoot框架在使用annotation的方式返回数据时效率比传统的response.write方式的运行效率要高出一截。
2、在SpringBoot框架下搭配分别搭配MyBatis、JPA、Hibernate时,其运行效率的差异不大,JPA的方式稍弱一点点。
本文属于“cp锋”的原创,虽然内容不是十分精品,但还望尊重本人的研究成果,转发时请注明转载并带上本页面链接,感谢~
Spring Boot做文件上传时出现了报错
The field file exceeds its maximum permitted size of 1048576 bytes
显示文件的大小超出了允许的范围。查看了官方文档,原来Spring Boot工程嵌入的tomcat限制了请求的文件大小默认为1MB,单次请求的文件的总数不能大于10Mb.要更改这个默认值需要在配置文件(如application.properties)中加入两个配置.
springboot 1.4之前是这样的:
multipart.maxFileSize = 10485760 //单个文件的大小 multipart.maxRequestSize = 10485760 //单次请求的文件的总大小
springboot 1.4之后是这样的:
spring.http.multipart.maxFileSize = 10485760 spring.http.multipart.maxRequestSize = 10485760
springboot 2.0之后是这样的:
spring.servlet.multipart.max-file-size = 10485760 spring.servlet.multipart.max-request-size = 10485760
注意:很多其他网站是让你们用10Mb这样的形式去赋值的,但事实上这样会报错,这里的单位是以字节b为单位的,我们可以调成他原来的1048576 bytes的10倍,也就是10MB大概等于10485760