Commit f6e69aca authored by nobodyiam's avatar nobodyiam

Performance tunning and misc improvement.

1. add aop to log spring jpa repository transaction
2. use gson to improve performance
3. specify http message converters for rest template
4. specify content type request header for release operation in portal
parent 94d583d9
...@@ -6,10 +6,12 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; ...@@ -6,10 +6,12 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient; import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
@SpringBootApplication @SpringBootApplication
@EnableEurekaClient @EnableEurekaClient
@EnableAspectJAutoProxy
public class AdminServiceApplication { public class AdminServiceApplication {
public static void main(String[] args) { public static void main(String[] args) {
ConfigurableApplicationContext context = new SpringApplicationBuilder(AdminServiceApplication.class).run(args); ConfigurableApplicationContext context = new SpringApplicationBuilder(AdminServiceApplication.class).run(args);
......
package com.ctrip.apollo; package com.ctrip.apollo;
import com.ctrip.apollo.common.controller.HttpMessageConverterConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScan.Filter; import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType; import org.springframework.context.annotation.FilterType;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration @Configuration
@ComponentScan(excludeFilters = {@Filter(type = FilterType.ASSIGNABLE_TYPE, value = { @ComponentScan(excludeFilters = {@Filter(type = FilterType.ASSIGNABLE_TYPE, value = {
SampleAdminServiceApplication.class, AdminServiceApplication.class})}) SampleAdminServiceApplication.class, AdminServiceApplication.class,
HttpMessageConverterConfiguration.class})})
@EnableAutoConfiguration @EnableAutoConfiguration
public class AdminServiceTestConfiguration { public class AdminServiceTestConfiguration {
......
package com.ctrip.apollo.adminservice.controller; package com.ctrip.apollo.adminservice.controller;
import javax.annotation.PostConstruct; import com.ctrip.apollo.AdminServiceTestConfiguration;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
...@@ -11,7 +11,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; ...@@ -11,7 +11,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.web.client.DefaultResponseErrorHandler; import org.springframework.web.client.DefaultResponseErrorHandler;
import org.springframework.web.client.RestTemplate; import org.springframework.web.client.RestTemplate;
import com.ctrip.apollo.AdminServiceTestConfiguration; import javax.annotation.PostConstruct;
@RunWith(SpringJUnit4ClassRunner.class) @RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = AdminServiceTestConfiguration.class) @SpringApplicationConfiguration(classes = AdminServiceTestConfiguration.class)
......
...@@ -20,7 +20,9 @@ import org.junit.Assert; ...@@ -20,7 +20,9 @@ import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity; import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.test.context.jdbc.Sql; import org.springframework.test.context.jdbc.Sql;
...@@ -69,11 +71,13 @@ public class ReleaseControllerTest extends AbstractControllerTest { ...@@ -69,11 +71,13 @@ public class ReleaseControllerTest extends AbstractControllerTest {
ItemDTO[].class); ItemDTO[].class);
Assert.assertEquals(3, items.length); Assert.assertEquals(3, items.length);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
MultiValueMap<String, String> parameters = new LinkedMultiValueMap<String, String>(); MultiValueMap<String, String> parameters = new LinkedMultiValueMap<String, String>();
parameters.add("name", "someReleaseName"); parameters.add("name", "someReleaseName");
parameters.add("comment", "someComment"); parameters.add("comment", "someComment");
HttpEntity<MultiValueMap<String, String>> entity = HttpEntity<MultiValueMap<String, String>> entity =
new HttpEntity<MultiValueMap<String, String>>(parameters, null); new HttpEntity<MultiValueMap<String, String>>(parameters, headers);
ResponseEntity<ReleaseDTO> response = restTemplate.postForEntity( ResponseEntity<ReleaseDTO> response = restTemplate.postForEntity(
"http://localhost:" + port + "/apps/" + app.getAppId() + "/clusters/" + cluster.getName() "http://localhost:" + port + "/apps/" + app.getAppId() + "/clusters/" + cluster.getName()
+ "/namespaces/" + namespace.getNamespaceName() + "/releases", + "/namespaces/" + namespace.getNamespaceName() + "/releases",
......
package com.ctrip.apollo.biz.aop;
import com.dianping.cat.Cat;
import com.dianping.cat.message.Message;
import com.dianping.cat.message.Transaction;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
/**
* @author Jason Song(song_s@ctrip.com)
*/
@Aspect
@Component
public class RepositoryAspect {
@Pointcut("execution(public * org.springframework.data.repository.Repository+.*(..))")
public void anyRepositoryMethod() {
}
@Around("anyRepositoryMethod()")
public Object invokeWithCatTransaction(ProceedingJoinPoint joinPoint) throws Throwable {
String name =
joinPoint.getSignature().getDeclaringType().getSimpleName() + "." + joinPoint.getSignature()
.getName();
Transaction catTransaction = Cat.newTransaction("SQL", name);
try {
Object result = joinPoint.proceed();
catTransaction.setStatus(Message.SUCCESS);
return result;
} catch (Throwable ex) {
catTransaction.setStatus(ex);
throw ex;
} finally {
catTransaction.complete();
}
}
}
...@@ -13,6 +13,8 @@ import org.apache.http.impl.client.HttpClientBuilder; ...@@ -13,6 +13,8 @@ import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicHeader; import org.apache.http.message.BasicHeader;
import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.web.HttpMessageConverters;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate; import org.springframework.web.client.RestTemplate;
...@@ -21,6 +23,8 @@ import com.google.common.io.BaseEncoding; ...@@ -21,6 +23,8 @@ import com.google.common.io.BaseEncoding;
@Component @Component
public class RestTemplateFactory implements FactoryBean<RestTemplate>, InitializingBean { public class RestTemplateFactory implements FactoryBean<RestTemplate>, InitializingBean {
@Autowired
private HttpMessageConverters httpMessageConverters;
private RestTemplate restTemplate; private RestTemplate restTemplate;
...@@ -49,7 +53,8 @@ public class RestTemplateFactory implements FactoryBean<RestTemplate>, Initializ ...@@ -49,7 +53,8 @@ public class RestTemplateFactory implements FactoryBean<RestTemplate>, Initializ
HttpClientBuilder.create().setDefaultCredentialsProvider(credentialsProvider) HttpClientBuilder.create().setDefaultCredentialsProvider(credentialsProvider)
.setDefaultHeaders(defaultHeaders).build(); .setDefaultHeaders(defaultHeaders).build();
restTemplate = new RestTemplate(new HttpComponentsClientHttpRequestFactory(httpClient)); restTemplate = new RestTemplate(httpMessageConverters.getConverters());
restTemplate.setRequestFactory(new HttpComponentsClientHttpRequestFactory(httpClient));
} }
} }
package com.ctrip.apollo.common.controller;
import com.google.common.collect.Lists;
import com.google.gson.GsonBuilder;
import org.springframework.boot.autoconfigure.web.HttpMessageConverters;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.ByteArrayHttpMessageConverter;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.json.GsonHttpMessageConverter;
import org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter;
import java.util.List;
/**
* Created by Jason on 5/11/16.
*/
@Configuration
public class HttpMessageConverterConfiguration {
@Bean
public HttpMessageConverters messageConverters() {
GsonHttpMessageConverter gsonHttpMessageConverter = new GsonHttpMessageConverter();
gsonHttpMessageConverter.setGson(
new GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ").create());
final List<HttpMessageConverter<?>> converters = Lists.newArrayList(
new ByteArrayHttpMessageConverter(), new StringHttpMessageConverter(),
new AllEncompassingFormHttpMessageConverter(), gsonHttpMessageConverter);
return new HttpMessageConverters() {
@Override
public List<HttpMessageConverter<?>> getConverters() {
return converters;
}
};
}
}
package com.ctrip.apollo.common.controller; package com.ctrip.apollo.common.controller;
import java.util.List;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.PageRequest;
import org.springframework.data.web.PageableHandlerMethodArgumentResolver; import org.springframework.data.web.PageableHandlerMethodArgumentResolver;
...@@ -10,6 +8,8 @@ import org.springframework.web.method.support.HandlerMethodArgumentResolver; ...@@ -10,6 +8,8 @@ import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer; import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import java.util.List;
@Configuration @Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter { public class WebMvcConfig extends WebMvcConfigurerAdapter {
...@@ -26,4 +26,5 @@ public class WebMvcConfig extends WebMvcConfigurerAdapter { ...@@ -26,4 +26,5 @@ public class WebMvcConfig extends WebMvcConfigurerAdapter {
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) { public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.ignoreAcceptHeader(true).defaultContentType(MediaType.APPLICATION_JSON); configurer.ignoreAcceptHeader(true).defaultContentType(MediaType.APPLICATION_JSON);
} }
} }
...@@ -6,6 +6,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; ...@@ -6,6 +6,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
/** /**
* Spring boot application entry point * Spring boot application entry point
...@@ -14,6 +15,7 @@ import org.springframework.context.ConfigurableApplicationContext; ...@@ -14,6 +15,7 @@ import org.springframework.context.ConfigurableApplicationContext;
*/ */
@SpringBootApplication @SpringBootApplication
@EnableEurekaServer @EnableEurekaServer
@EnableAspectJAutoProxy
public class ConfigServiceApplication { public class ConfigServiceApplication {
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
......
...@@ -22,6 +22,7 @@ import javax.annotation.PostConstruct; ...@@ -22,6 +22,7 @@ import javax.annotation.PostConstruct;
@SpringApplicationConfiguration(classes = AbstractBaseIntegrationTest.TestConfiguration.class) @SpringApplicationConfiguration(classes = AbstractBaseIntegrationTest.TestConfiguration.class)
@WebIntegrationTest(randomPort = true) @WebIntegrationTest(randomPort = true)
public abstract class AbstractBaseIntegrationTest { public abstract class AbstractBaseIntegrationTest {
RestTemplate restTemplate = new TestRestTemplate("user", ""); RestTemplate restTemplate = new TestRestTemplate("user", "");
@PostConstruct @PostConstruct
......
...@@ -11,6 +11,8 @@ import com.ctrip.apollo.core.dto.NamespaceDTO; ...@@ -11,6 +11,8 @@ import com.ctrip.apollo.core.dto.NamespaceDTO;
import com.ctrip.apollo.core.dto.ReleaseDTO; import com.ctrip.apollo.core.dto.ReleaseDTO;
import org.springframework.http.HttpEntity; import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.LinkedMultiValueMap;
...@@ -130,11 +132,13 @@ public class AdminServiceAPI { ...@@ -130,11 +132,13 @@ public class AdminServiceAPI {
public ReleaseDTO release(String appId, Env env, String clusterName, String namespace, public ReleaseDTO release(String appId, Env env, String clusterName, String namespace,
String releaseBy, String comment) { String releaseBy, String comment) {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
MultiValueMap<String, String> parameters = new LinkedMultiValueMap<String, String>(); MultiValueMap<String, String> parameters = new LinkedMultiValueMap<String, String>();
parameters.add("name", releaseBy); parameters.add("name", releaseBy);
parameters.add("comment", comment); parameters.add("comment", comment);
HttpEntity<MultiValueMap<String, String>> entity = HttpEntity<MultiValueMap<String, String>> entity =
new HttpEntity<MultiValueMap<String, String>>(parameters, null); new HttpEntity<MultiValueMap<String, String>>(parameters, headers);
ResponseEntity<ReleaseDTO> response = ResponseEntity<ReleaseDTO> response =
restTemplate restTemplate
.postForEntity( .postForEntity(
......
...@@ -11,6 +11,8 @@ import javax.annotation.PostConstruct; ...@@ -11,6 +11,8 @@ import javax.annotation.PostConstruct;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.web.HttpMessageConverters;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory; import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
...@@ -31,7 +33,10 @@ public class ServiceLocator { ...@@ -31,7 +33,10 @@ public class ServiceLocator {
private static final int DEFAULT_TIMEOUT_MS = 1000; private static final int DEFAULT_TIMEOUT_MS = 1000;
private RestTemplate restTemplate = new RestTemplate(); private RestTemplate restTemplate;
@Autowired
private HttpMessageConverters httpMessageConverters;
private Map<Env, List<ServiceDTO>> serviceCaches = new ConcurrentHashMap<Env, List<ServiceDTO>>(); private Map<Env, List<ServiceDTO>> serviceCaches = new ConcurrentHashMap<Env, List<ServiceDTO>>();
...@@ -81,6 +86,7 @@ public class ServiceLocator { ...@@ -81,6 +86,7 @@ public class ServiceLocator {
@PostConstruct @PostConstruct
private void postConstruct() { private void postConstruct() {
restTemplate = new RestTemplate(httpMessageConverters.getConverters());
if (restTemplate.getRequestFactory() instanceof SimpleClientHttpRequestFactory) { if (restTemplate.getRequestFactory() instanceof SimpleClientHttpRequestFactory) {
SimpleClientHttpRequestFactory rf = SimpleClientHttpRequestFactory rf =
(SimpleClientHttpRequestFactory) restTemplate.getRequestFactory(); (SimpleClientHttpRequestFactory) restTemplate.getRequestFactory();
......
package com.ctrip.apollo.portal; package com.ctrip.apollo.portal;
import javax.annotation.PostConstruct; import com.ctrip.apollo.PortalApplication;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
...@@ -11,7 +11,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; ...@@ -11,7 +11,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.web.client.DefaultResponseErrorHandler; import org.springframework.web.client.DefaultResponseErrorHandler;
import org.springframework.web.client.RestTemplate; import org.springframework.web.client.RestTemplate;
import com.ctrip.apollo.PortalApplication; import javax.annotation.PostConstruct;
@RunWith(SpringJUnit4ClassRunner.class) @RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = PortalApplication.class) @SpringApplicationConfiguration(classes = PortalApplication.class)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment