Внедрить службу статистики блогов с помощью Spring Boot

Spring Boot Redis задняя часть Spring Java EE

Что касается внутренней разработки, то в эпоху микросервисов, сеток серверов и других концепций нельзя терять способность к непрерывному обучению, поэтому арендодатель недавно изучил множество технологий RPC, NETTY, Spring Boot и других. Кроме того, функция статистики чтения блога арендодателя использует стороннюю функцию статистики количества, которая соответствует HEXO, что является рождением поездки арендодателя, чтобы заменить основные функции, разработанные им самим.

Сгенерировать проект через SPRING INITIALIZR

spring initspring init
Как показано выше, через официальный SpringSpring InitialНа сайте генерируется проект.Структура каталогов проекта выглядит следующим образом:

  • Структура каталогов
- src
    -main
        -java
            -package
                #主函数,启动类,运行它如果运行了 Tomcat、Jetty、Undertow 等容器
                -SpringbootApplication    
        -resouces
            #存放静态资源 js/css/images 等
            - statics
            #存放 html 模板文件
            - templates
            #主要的配置文件,SpringBoot启动时候会自动加载application.yml/application.properties        
            - application.yml
    #测试文件存放目录        
    -test
 # pom.xml 文件是Maven构建的基础,里面包含了我们所依赖JAR和Plugin的信息
- pom
  • пом-зависимость

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

	<groupId>com.*</groupId>
	<artifactId>*-*</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>base-service</name>
	<description>Demo project for Spring Boot</description>

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

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-lang3</artifactId>
			<version>3.6</version>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-redis</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-test</artifactId>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>com.almende.eve</groupId>
			<artifactId>eve-bundle-full</artifactId>
			<version>3.1.1</version>
		</dependency>
	</dependencies>

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

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

Реализовать логику хранилища Redis

Причина выбора Redis вместо базы данных заключается в том, что Redis предоставляет богатые структуры данных и стратегии сохранения данных.Кроме того, Redis основан на памяти, которая более чем на порядок быстрее, чем базы данных. Сценарий подсчета количества прочтений все же имеет определенные требования к скорости обработки интерфейса, поэтому в качестве БД для подсчета количества прочтений арендодатель выбрал redis.
Ниже приведен базовый код работы Redis. Он относительно прост. Арендодатель опубликует код без дальнейшего уточнения.

  • интерфейсный класс Redis

    public interface RedisService {
        public boolean set(final String key, final String value);
        public String get(final String key);
        public String incr(final String key);
    }
    
  • Класс реализации Redis


@Service
public class RedisServiceImpl implements RedisService {

    @Resource
    private RedisTemplate<String, ?> redisTemplate;

    @Override
    public boolean set(final String key, final String value) {
        boolean result = redisTemplate.execute(new RedisCallback<Boolean>() {
            @Override
            public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
                RedisSerializer<String> serializer = redisTemplate.getStringSerializer();
                connection.set(serializer.serialize(key), serializer.serialize(value));
                return true;
            }
        });
        return result;
    }

    @Override
    public String incr(final String key) {
        String incr = redisTemplate.execute(new RedisCallback<String>() {
            @Override
            public String doInRedis(RedisConnection redisConnection) throws DataAccessException {
                RedisSerializer<String> serializer = redisTemplate.getStringSerializer();
                Long value = redisConnection.incr(serializer.serialize(key));
                return String.valueOf(value);
            }
        });
        return incr;
    }

    @Override
    public String get(final String key){
        String result = redisTemplate.execute(new RedisCallback<String>() {
            @Override
            public String doInRedis(RedisConnection connection) throws DataAccessException {
                RedisSerializer<String> serializer = redisTemplate.getStringSerializer();
                byte[] value =  connection.get(serializer.serialize(key));
                return serializer.deserialize(value);
            }
        });
        return result;
    }

}

Реализация интерфейса статистики чтения блога

Базовая бизнес-логика статистики чтения блогов заключается в том, что blogId, соответствующий каждому блогу, используется в качестве ключа Redis, а количество посещений — это значение, соответствующее этому ключу.Каждый раз при доступе к интерфейсу соответствующий blogId будет увеличиваться. и будет возвращено соответствующее значение blogId. Структура данных redis, выбранная арендодателем, — это Stirng of redis. Ниже приведен основной код арендодателя для реализации логики:



/**
 * 统计博客阅读次数.
 *
 * @author wuhf
 * @Date 2018/6/15 15:59
 **/
@RestController
@RequestMapping("/")
public class BlogReadCountController {

    private static String ALLOW_REQUEST_URL = "******";
    private static String ILLEGAL_CHARACTERS = "*";
    private static String DEFAULT_READ_COUNT = "1";
    private static Logger logger = LoggerFactory.getLogger(BlogReadCountController.class);

    @Autowired
    private RedisService redisService;

    @ResponseBody
    @RequestMapping("/*_*")
    public ResultCode blogReadCountIncr(HttpServletRequest request,String blogId) {
        ResultCode resultCode = new ResultCode();
        try {
            logger.info(">>>>>> method blogReadCountIncr exec , request params is : {}",blogId);
            String readCount = redisService.get(blogId);
            if (StringUtils.isBlank(readCount)) {
                
                if (!blogId.startsWith(ALLOW_REQUEST_URL)||blogId.contains(ILLEGAL_CHARACTERS)) {
                    resultCode.setCode(Messages.API_ERROR_CODE);
                    resultCode.setMsg(Messages.API_ERROR_MSG);
                    return resultCode;
                }

                redisService.set(blogId,DEFAULT_READ_COUNT);
                readCount = DEFAULT_READ_COUNT;
            } else {
                readCount = redisService.incr(blogId);
            }
            logger.info(">>>>>> readCount is : {}",readCount);
            resultCode.setCode(Messages.SUCCESS_CODE);
            resultCode.setMsg(Messages.SUCCESS_MSG);
            resultCode.setData(readCount);
            return resultCode;
        } catch (Exception e) {
            e.printStackTrace();
            resultCode.setCode(Messages.API_ERROR_CODE);
            resultCode.setMsg(Messages.API_ERROR_MSG);
            return resultCode;
        }
    }
}

Яма, обнаруженная в процессе реализации

  • Установите номер порта для запуска приложения
server.port=9401
  • Установить путь для доступа к приложению

Путь доступа по умолчанию приложения Spring Boot по-прежнему "/". Хозяин здесь немного пострадал. Он использовал http://имя проекта:порт для доступа к сервису, но он не был доступен. Настройки в файле конфигурации являются следующими

server.servlet.context-path=/项目名

резюме

В настоящее время многие большие ребята написали учебники по SpringBoot. Если есть какие-либо сходства, пожалуйста, игнорируйте их. Эта статья завершена моим собственным реальным боем и ямой, на которую наступил хозяин. Кроме того, эта статья основана на последних spring-boot-starter-parent: написано 2.0.3.RELEASE.

Дополнительный

Арендодатель построил колесо. LIGHTCONF — это платформа управления конфигурацией, основанная на Netty. Ее основная цель — «предоставить унифицированную услугу управления конфигурацией для бизнеса», которую можно использовать «из коробки». Если вы заинтересованы, дайте звезду, чтобы поддержать это.