操作细节:什么是SEO优化?怎么去进行SEO优化操作?
优采云 发布时间: 2022-11-28 23:55操作细节:什么是SEO优化?怎么去进行SEO优化操作?
字符数(39),推荐长度(小于等于100字节)
标题的关键词放置方式:
标题中关键词之间的“符号”,一般使用“-”或“|”,不要使用“_”下划线。
一般标题格式:
1.首页标题:网站名称-Core关键词
2.列表(频道、栏目、话题)页面标题:栏目名称-站点名称-核心关键词
3.显示具体内容页面(三级子页面)页面标题:文章名称-栏目名称-网站名称
4、单个网页的Title不要过于频繁的更改,也不要频繁的修改Title内容。
5、保持不同网页的标题内容不同。
网页描述元描述
1、描写的内容要吸引读者,句子流畅优美。
2. 包括大量命中 关键词,尤其是扩展 关键词 和长尾 关键词。
3、首页Description是为整个专区的内容写的;
列表栏目列表页的Description是为整个栏目内容编写的;
具体文章内容页的Description是为本文写的,主要包括长尾关键词。
4、限128个汉字,200个汉字
关键字关键词标签的优化
1、注意写作:是“关键词”,不是“关键词”;在两个 关键词 "," 半角逗号之间(英文输入法状态)。
" />
2、请注意语法:
关键词是meta的一部分,必须写在里面,根据SE蜘蛛爬虫的爬行习惯,
按照标题、关键词和描述的顺序写。
页面标题
3.关键字关键词不要超过5个,几个就够了,以免被SE惩罚堆砌关键词。
4、keywords关键字标签中的内容要与网页的核心内容相关。确保使用过的 关键词 出现在网页的文本中。不要写与网页内容无关的关键词关键词。
5、不要重复使用关键字关键词,否则可能会被搜索引擎惩罚。
内容优化
根据技术判断,SE根据文章是否“原创”将文章分为三类:原创文章、伪原创文章和抄袭文章。
原创:指本站自行创作的文章。这篇文章反映在SE上是网上“首发”。独创性具有最高的权重。
伪原创文章:修改其他网站的文章内容,在原创文章的基础上做一些修改,截首尾,或增减,调整段落顺序等,然后发布为你的自己的创作。
抄袭文章:完全复制其他网站上的文章或在一定程度上改变其形式或内容的文章。网上和这篇文章内容相同的网页很多,这种文章权重最低。
1.优化:【二级】
权重:原创文章>伪原创>抄袭文章原创内容最好
一是多发表原创文章。
二、对于多次转载的文章,对于从其他网站转载复制的文章,尽量修改成“伪原创文章”。在保持文章内容基本准确、流畅、完整的同时,对文章进行修改(包括重新切分、改变顺序、改词、改变语言表达、增减内容等),使文章“伪-原来的”。
2、文章合理排版【二级】
搜索引擎喜欢文章长度在1000-2000字的网页,对于很长的文章分页是合理的。将文章中的“副标题”分隔成自然段落,重要的关键词、句子加粗或使用其他颜色。
1)每篇文章的主题
" />
页面的主题越紧密,搜索引擎对它的排名就越好。有时你会发现自己写了很长的文章,涵盖了一些不同的主题,而且相关性不高,所以在搜索引擎上的排名也不好。如果您关心搜索引擎排名,最好将此类文章切割成几篇主题更接近的文章。
2)写一篇长度合适的文章
太短的文章无法获得更高的排名,每篇文章一般控制在300字以上。另一方面,不要让文章看起来太长,因为这样不利于你保持关键词的密度,文章看起来也不紧凑。研究表明,过长的文章会大大减少第一眼就选择关闭文章的读者数量。
不作弊,免遭处罚
搜索引擎优化必须了解规则,以避免无意中使用这些技术而受到搜索引擎的惩罚。
关键词关键词堆砌
隐藏文本/链接 (Hidden Text/ link )
门页
无用的元标签
隐形页面
链接农场
重定向(Re-Direct)
1. 误导 关键词
在与页面无关的页面中使用具有误导性的 关键词 来吸引访问者访问该站点并查询该主题。这种做法严重影响了搜索引擎所提供结果的相关性和客观性,为搜索引擎所痛恨。
2. 很多可重复性 关键词
某关键词密度大于8%,又称为“关键词堆叠欺骗”,利用搜索引擎对网页中出现的关键词的高度关注,进行不合理的关键词(过度)重复。
其他类似的做法包括在 HTML mate 元标记中填充关键字或使用多个关键字元标记来提高 关键词 的相关性。这种技术很容易被搜索引擎检测到并受到相应的惩罚。
以上是SEO优化的具体操作范围和相关规则。其中,网站SEO还有一种很常见的方法,就是通过网站好友链接进行优化。
当然,SEO不仅仅是上面提到的那些。SEO可以说是一项非常专业的工作,需要时间和精力长期投入和执行。但它带来的结果,一定绝对值得为之付出的精力。如果你有更多好的技巧和内容,欢迎投稿
解决方案:Java在线教育项目 第十二天热点文章处理
热点文章处理目标1 热点文章处理-功能需求
为了更好的为用户提供文章,上线热门文章计算功能,从两个维度计算热点文章数据:一是从数据库的定时任务计算,二是从实时流计算根据时间窗口接收。计算结果存储在数据库中,供用户查询。
核心流程请查看data文件夹:热点文章计算流程.pdf
2 热点文章处理——热点数据计算 2.1 思路分析 2.2 实体类
com.heima.model.article.pojos.ApHotArticles
@Data
public class ApHotArticles {
private Integer id;
private Integer entryId;
private Integer tagId;
private String tagName;
private Integer score;
private Integer articleId;
private Date releaseDate;
private Date createdTime;
private Integer provinceId;
private Integer cityId;
private Integer countyId;
private Integer isRead;
}
2.3 映射器实现
(1) ApHotArticlesMapper
创建类 com.heima.model.mappers.app.ApHotArticlesMapper
public interface ApHotArticlesMapper {
/**
* 插入热文章数据
*
* @param record
* @return
*/
int insert(ApHotArticles record);
/**
* 移除传入日期之前的文章
*
* @param removeDate
* @return
*/
int removeHotArticle(String removeDate);
/**
* 根据ID删除
*
* @param id
*/
void deleteById(Integer id);
/**
* 查询热文章ID
*
* @param entryId
* @param dto
* @return
*/
List loadArticleIdListByEntryId(Integer entryId, ArticleHomeDto dto, short type);
List selectList(ApHotArticles apHotArticles);
List selectExpireMonth();
/**
* 查询今天最大ID
* @param today
* @return
*/
Integer selectTodayMaxScore(String today);
/**
* 文章已经阅读
* @param entryId
* @param articleId
* @return
*/
int updateReadStatus(Integer entryId, Integer articleId);
List loadHotListByLocation(@Param("dto") ArticleHomeDto dto, short type);
}
ApHotArticlesMapper.xml
DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
id, entry_id, tag_id, tag_name, score, article_id,
province_id,city_id,county_id,is_read,release_date,
created_time
and entry_id = #{entryId}
and tag_id = #{tagId}
and tag_name = #{tagName}
and score = #{score}
and article_id = #{articleId}
select
from ap_hot_articles
select
from ap_hot_articles
where created_time > DATE_SUB(CURDATE(), INTERVAL 1 MONTH)
insert into ap_hot_articles
id,
entry_id,
tag_id,
tag_name,
score,
article_id,
province_id,
city_id,
county_id,
is_read,
release_date,
created_time,
#{id,jdbcType=INTEGER},
#{entryId,jdbcType=INTEGER},
#{tagId,jdbcType=INTEGER},
#{tagName,jdbcType=VARCHAR},
#{score,jdbcType=INTEGER},
#{articleId,jdbcType=INTEGER},
#{provinceId,jdbcType=INTEGER},
#{cityId,jdbcType=INTEGER},
#{countyId,jdbcType=INTEGER},
#{isRead,jdbcType=TINYINT},
#{releaseDate,jdbcType=TIMESTAMP},
#{createdTime,jdbcType=TIMESTAMP},
delete from ap_hot_articles
where created_time < #{removeDate}
delete from ap_hot_articles where id= #{id}
select * from ap_hot_articles
entry_id = #{entryId} and is_read=0
and release_date #{dto.minBehotTime}
and release_date ]]> #{dto.maxBehotTime}
and tag_id = #{dto.tag}
limit #{dto.size}
select max(score) from ap_hot_articles
where created_time > #{today}
update ap_hot_articles set is_read = 1
where entry_id = #{entryId} and article_id = #{articleId}
select * from ap_hot_articles a
a.entry_id = 0
and a.province_id=#{dto.provinceId}
and a.city_id=#{dto.cityId}
and a.county_id=#{dto.countyId}
and a.release_date #{dto.minBehotTime}
and a.release_date ]]> #{dto.maxBehotTime}
and a.tag_id = #{dto.tag}
<p>
" />
limit #{dto.size}
</p>
(2)修改com.heima.article.mysql.core.model.mappers.app.ApArticleMapper,增加一个基于发布时间的查询方法
/**
* 抽取最近的文章数据用于计算热文章
*
* @param lastDate
* @return
*/
List loadLastArticleForHot(String lastDate);
ApArticleMapper.xml
select
from ap_article
where publish_time > #{lastDate}
(3)修改com.heima.model.mappers.app.ApBehaviorEntryMapper添加方法
List selectAllEntry();
ApBehaviorEntryMapper.xml
select * from ap_behavior_entry
2.4 服务代码实现
(1) AppHotArticle服务
创建类:com.heima.article.service.AppHotArticleService
定义热点文章计算接口:
public interface AppHotArticleService {
/**
* 计算热文章
*/
public void computeHotArticle();
}
(2)AppHotArticleServiceImpl
创建类:com.heima.login.service.AppHotArticleServiceImpl
@Service
@SuppressWarnings("all")
public class AppHotArticleServiceImpl implements AppHotArticleService {
@Autowired
private ApHotArticlesMapper apHotArticlesMapper;
@Autowired
private ApArticleMapper apArticleMapper;
@Autowired
private ApBehaviorEntryMapper apBehaviorEntryMapper;
@Autowired
private AdChannelMapper adChannelMapper;
@Autowired
private StringRedisTemplate redisTemplate;
@Override
public void computeHotArticle() {
//计算逻辑
String lastDay = DateTime.now().minusDays(1).toString("yyyy-MM-dd 00:00:00");
List articleList = apArticleMapper.loadLastArticleForHot(lastDay);
List hotArticlesList = computeHotArticle(articleList);
//缓存频道到redis
cacheTagToRedis(articleList);
//所有用户
List entryList = apBehaviorEntryMapper.selectAllEntry();
for(ApHotArticles hot : hotArticlesList){
//插入热文章数据
apHotArticlesMapper.insert(hot);
//为每位用户保存一份
saveHotArticleForEntryList(hot, entryList);
//热文章计算完成发送给图片队列
//通知处理热文章图片
//kafkaSender.sendHotArticleMessage(hot);
}
}
/**
* 计算热文章
* @param articleList
* @return
*/
private List computeHotArticle(List articleList) {
List hotArticlesList = Lists.newArrayList();
ApHotArticles hot = null;
for (ApArticle a : articleList) {
hot = initHotBaseApArticle(a);
Integer score = computeScore(a);
hot.setScore(score);
hotArticlesList.add(hot);
}
hotArticlesList.sort(new Comparator() {
@Override
public int compare(ApHotArticles o1, ApHotArticles o2) {
return o1.getScore() 1000){
return hotArticlesList.subList(0,1000);
}
return hotArticlesList;
}
/**
* 初始化热文章属性
* @param article
* @return
*/
private ApHotArticles initHotBaseApArticle(ApArticle article){
ApHotArticles hot = new ApHotArticles();
hot.setEntryId(0);
//根据articleID查询
hot.setTagId(article.getChannelId());
hot.setTagName(article.getChannelName());
hot.setScore(0);
hot.setArticleId(article.getId());
//设置省市区
hot.setProvinceId(article.getProvinceId());
hot.setCityId(article.getCityId());
hot.setCountyId(article.getCountyId());
hot.setIsRead(0);
//日期
hot.setReleaseDate(article.getPublishTime());
hot.setCreatedTime(new Date());
return hot;
}
/**
* 计算热度分规则 1.0
* @param a
* @return
*/
private Integer computeScore(ApArticle a) {
Integer score = 0;
if(a.getLikes()!=null){
score += a.getLikes();
}
if(a.getCollection()!=null){
score += a.getCollection();
}
if(a.getComment()!=null){
score += a.getComment();
}
if(a.getViews()!=null){
score += a.getViews();
}
return score;
}
/**
* 为每位用户保存一份
* @param hot
* @param entryList
*/
private void saveHotArticleForEntryList(ApHotArticles hot, List entryList) {
for (ApBehaviorEntry entry: entryList){
hot.setEntryId(entry.getId());
apHotArticlesMapper.insert(hot);
}
}
/**
* 缓存频道首页到redis
* @param articlesList
*/
private void cacheTagToRedis(List articlesList) {
List channels = adChannelMapper.selectAll();
List temp = null;
for (AdChannel channel : channels){
temp = articlesList.stream().
filter(p -> p.getChannelId().equals(channel.getId()))
.collect(Collectors.toList());
if(temp.size()>30){
temp = temp.subList(0,30);
}
if(temp.size()==0){
redisTemplate.opsForValue().set(ArticleConstans.HOT_ARTICLE_FIRST_PAGE+channel.getId(), "");
continue;
}
redisTemplate.opsForValue().set(ArticleConstans.HOT_ARTICLE_FIRST_PAGE+channel.getId(), JSON.toJSONString(temp));
}
}
}
添加的常量:mon.article.constans.ArticleConstans
public class ArticleConstans {
public static final String HOT_ARTICLE_FIRST_PAGE = "hot_article_first_page_";
}
整合redis
添加类:com.heima.article.config.RedisConfig
@Configuration
@ComponentScan("com.heima.common.redis")
public class RedisConfig {
}
注意:如果没有密码访问redis,需要删除密码项
2.5 定时任务
整合quartz,注意把前面的mysql整合成一个配置类,放在quartz之前
@Configuration
@ComponentScan({"com.heima.common.mysql.core","com.heima.common.common.init","com.heima.common.quartz"})
@EnableScheduling
public class InitConfig {
}
AppHotArticle石英
创建类:com.heima.article.quartz.AppHotArticleQuartz
这个类的实现比较简单,引入Service并调用即可:
@Component
@Log4j2
public class AppHotArticleQuartz extends AbstractJob {
@Override
public String[] triggerCron() {
return new String[]{"0 0/2 * * * ?"};
}
@Autowired
private AppHotArticleService appHotArticleService;
@Override
protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
long currentTimeMillis = System.currentTimeMillis();
log.info("开始计算热文章数据");
appHotArticleService.computeHotArticle();
log.info("计算热文章数据完成,耗时:{}",System.currentTimeMillis()-currentTimeMillis);
}
@Override
public String descTrigger() {
return "每天00:05分执行一次";
}
}
创建quartz表结构,方便集群使用定时任务
DROP TABLE IF EXISTS ARTICLE_QRTZ_FIRED_TRIGGERS;
DROP TABLE IF EXISTS ARTICLE_QRTZ_PAUSED_TRIGGER_GRPS;
DROP TABLE IF EXISTS ARTICLE_QRTZ_SCHEDULER_STATE;
DROP TABLE IF EXISTS ARTICLE_QRTZ_LOCKS;
DROP TABLE IF EXISTS ARTICLE_QRTZ_SIMPLE_TRIGGERS;
DROP TABLE IF EXISTS ARTICLE_QRTZ_SIMPROP_TRIGGERS;
DROP TABLE IF EXISTS ARTICLE_QRTZ_CRON_TRIGGERS;
DROP TABLE IF EXISTS ARTICLE_QRTZ_BLOB_TRIGGERS;
DROP TABLE IF EXISTS ARTICLE_QRTZ_TRIGGERS;
DROP TABLE IF EXISTS ARTICLE_QRTZ_JOB_DETAILS;
DROP TABLE IF EXISTS ARTICLE_QRTZ_CALENDARS;
CREATE TABLE ARTICLE_QRTZ_JOB_DETAILS
(
SCHED_NAME VARCHAR(120) NOT NULL,
JOB_NAME VARCHAR(200) NOT NULL,
JOB_GROUP VARCHAR(200) NOT NULL,
DESCRIPTION VARCHAR(250) NULL,
JOB_CLASS_NAME VARCHAR(250) NOT NULL,
IS_DURABLE VARCHAR(1) NOT NULL,
IS_NONCONCURRENT VARCHAR(1) NOT NULL,
IS_UPDATE_DATA VARCHAR(1) NOT NULL,
REQUESTS_RECOVERY VARCHAR(1) NOT NULL,
JOB_DATA BLOB NULL,
PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
);
CREATE TABLE ARTICLE_QRTZ_TRIGGERS
(
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
JOB_NAME VARCHAR(200) NOT NULL,
JOB_GROUP VARCHAR(200) NOT NULL,
DESCRIPTION VARCHAR(250) NULL,
NEXT_FIRE_TIME BIGINT(13) NULL,
PREV_FIRE_TIME BIGINT(13) NULL,
PRIORITY INTEGER NULL,
TRIGGER_STATE VARCHAR(16) NOT NULL,
TRIGGER_TYPE VARCHAR(8) NOT NULL,
START_TIME BIGINT(13) NOT NULL,
END_TIME BIGINT(13) NULL,
CALENDAR_NAME VARCHAR(200) NULL,
MISFIRE_INSTR SMALLINT(2) NULL,
JOB_DATA BLOB NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
<p>
" />
FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
REFERENCES ARTICLE_QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP)
);
CREATE TABLE ARTICLE_QRTZ_SIMPLE_TRIGGERS
(
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
REPEAT_COUNT BIGINT(7) NOT NULL,
REPEAT_INTERVAL BIGINT(12) NOT NULL,
TIMES_TRIGGERED BIGINT(10) NOT NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES ARTICLE_QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
);
CREATE TABLE ARTICLE_QRTZ_CRON_TRIGGERS
(
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
CRON_EXPRESSION VARCHAR(200) NOT NULL,
TIME_ZONE_ID VARCHAR(80),
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES ARTICLE_QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
);
CREATE TABLE ARTICLE_QRTZ_SIMPROP_TRIGGERS
(
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
STR_PROP_1 VARCHAR(512) NULL,
STR_PROP_2 VARCHAR(512) NULL,
STR_PROP_3 VARCHAR(512) NULL,
INT_PROP_1 INT NULL,
INT_PROP_2 INT NULL,
LONG_PROP_1 BIGINT NULL,
LONG_PROP_2 BIGINT NULL,
DEC_PROP_1 NUMERIC(13,4) NULL,
DEC_PROP_2 NUMERIC(13,4) NULL,
BOOL_PROP_1 VARCHAR(1) NULL,
BOOL_PROP_2 VARCHAR(1) NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES ARTICLE_QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
);
CREATE TABLE ARTICLE_QRTZ_BLOB_TRIGGERS
(
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
BLOB_DATA BLOB NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES ARTICLE_QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
);
CREATE TABLE ARTICLE_QRTZ_CALENDARS
(
SCHED_NAME VARCHAR(120) NOT NULL,
CALENDAR_NAME VARCHAR(200) NOT NULL,
CALENDAR BLOB NOT NULL,
PRIMARY KEY (SCHED_NAME,CALENDAR_NAME)
);
CREATE TABLE ARTICLE_QRTZ_PAUSED_TRIGGER_GRPS
(
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP)
);
CREATE TABLE ARTICLE_QRTZ_FIRED_TRIGGERS
(
SCHED_NAME VARCHAR(120) NOT NULL,
ENTRY_ID VARCHAR(95) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
INSTANCE_NAME VARCHAR(200) NOT NULL,
FIRED_TIME BIGINT(13) NOT NULL,
SCHED_TIME BIGINT(13) NOT NULL,
PRIORITY INTEGER NOT NULL,
STATE VARCHAR(16) NOT NULL,
JOB_NAME VARCHAR(200) NULL,
JOB_GROUP VARCHAR(200) NULL,
IS_NONCONCURRENT VARCHAR(1) NULL,
REQUESTS_RECOVERY VARCHAR(1) NULL,
PRIMARY KEY (SCHED_NAME,ENTRY_ID)
);
CREATE TABLE ARTICLE_QRTZ_SCHEDULER_STATE
(
SCHED_NAME VARCHAR(120) NOT NULL,
INSTANCE_NAME VARCHAR(200) NOT NULL,
LAST_CHECKIN_TIME BIGINT(13) NOT NULL,
CHECKIN_INTERVAL BIGINT(13) NOT NULL,
PRIMARY KEY (SCHED_NAME,INSTANCE_NAME)
);
CREATE TABLE ARTICLE_QRTZ_LOCKS
(
SCHED_NAME VARCHAR(120) NOT NULL,
LOCK_NAME VARCHAR(40) NOT NULL,
PRIMARY KEY (SCHED_NAME,LOCK_NAME)
);
commit;
</p>
需要在mycat中配置scheme.xml文件,配置11张新表
2.6 测试
刚开始项目测试
3 文章热点数据实时计算 3.1 行为采集和发送消息 3.1.1 定义消息名称
maven_test.properties
# app产生的更新文章数据消息
kafka.topic.article-update-bus=heima.topic.app.article.update.bus.test
kafka.properties
# app产生的更新文章数据消息
kafka.topic.article-update-bus=${kafka.topic.article-update-bus}
在 mon.kafka.KafkaTopicConfig 类中添加新属性,添加消息名称
// 更新文章数据的消息topic
String articleUpdateBus;
3.1.2 定时消息封装的实体类
封装特定消息的实体类
com.heima.model.mess.app.UpdateArticle
@Data
public class UpdateArticle implements Serializable {
private static final long serialVersionUID = 332498820763181265L;
// 修改文章的字段类型
private UpdateArticleType type;
// 文章ID
private Integer articleId;
// 修改数据的增量,可为正负
private Integer add;
private Integer apUserId;
private Integer behaviorId;
public enum UpdateArticleType{
COLLECTION,COMMENT,LIKES,VIEWS;
}
}
消息传输的实体类
mon.kafka.messages.app.UpdateArticleMessage
public class UpdateArticleMessage extends KafkaMessage {
public UpdateArticleMessage(){}
public UpdateArticleMessage(UpdateArticle data) {
super(data);
}
@Override
public String getType() {
return "update-article";
}
}
3.1.3 添加发送消息的方法
修改mon.kafka.KafkaSender,
/**
* 发送修改文章请求消息
*
* @param message
*/
public void sendArticleUpdateBus(KafkaMessage message) {
this.sendMesssage(kafkaTopicConfig.getArticleUpdateBus(), UUID.randomUUID().toString(), message);
}
3.1.4 用户行为消息发送类封装
采集
于 heima-leadnews-behavior 模块
创建消息发送类:com.heima.behavior.kafka.BehaviorMessageSender
@Component
public class BehaviorMessageSender {
@Autowired
KafkaSender kafkaSender;
/**
* 发送+1的消息
* @param message
* @param isSendToArticle
*/
@Async
public void sendMessagePlus(KafkaMessage message,Long apUserId,boolean isSendToArticle){
if(isSendToArticle){
UpdateArticleMessage temp = parseMessage(message,apUserId,1);
if(temp!=null)
kafkaSender.sendArticleUpdateBus(temp);
}
}
/**
* 发送-1的消息
* @param message
* @param isSendToArticle
*/
@Async
public void sendMessageReduce(KafkaMessage message,Long apUserId,boolean isSendToArticle){
if(isSendToArticle){
UpdateArticleMessage temp = parseMessage(message,apUserId,-1);
if(temp!=null)
kafkaSender.sendArticleUpdateBus(temp);
}
}
/**
* 转换行为消息为修改位置的消息
* @param message
* @param step
* @return
*/
private UpdateArticleMessage parseMessage(KafkaMessage message,Long apUserId,int step){
UpdateArticle ua = new UpdateArticle();
if(apUserId!=null) ua.setApUserId(apUserId.intValue());
// 转换为收藏的消息
if(message instanceof UserCollectionMessage){
UserCollectionMessage m = (UserCollectionMessage)message;
// 只发收藏文章的消息
if(m.getData().getType()== ApCollection.Type.ARTICLE.getCode()) {
ua.setType(UpdateArticle.UpdateArticleType.COLLECTION);
ua.setAdd(step);
ua.setArticleId(m.getData().getEntryId());
ua.setBehaviorId(m.getData().getBehaviorEntryId());
}
}else if(message instanceof UserLikesMessage){
UserLikesMessage m = (UserLikesMessage)message;
// 只发文章的喜欢消息
if(m.getData().getType()== ApLikesBehavior.Type.ARTICLE.getCode()){
ua.setType(UpdateArticle.UpdateArticleType.LIKES);
ua.setAdd(step);
ua.setArticleId(m.getData().getEntryId());
ua.setBehaviorId(m.getData().getBehaviorEntryId());
}
}else if(message instanceof UserReadMessage){
UserReadMessage m = (UserReadMessage) message;
ua.setType(UpdateArticle.UpdateArticleType.VIEWS);
ua.setAdd(step);
ua.setArticleId(m.getData().getArticleId());
ua.setBehaviorId(m.getData().getEntryId());
}
if(ua.getArticleId()!=null){
return new UpdateArticleMessage(ua);
}
return null;
}
}
3.1.5 特定行为消息发送
(1) 喜欢
创建封装like消息的实体类
mom.kafka.messages.behavior.UserLikesMessage
public class UserLikesMessage extends KafkaMessage {
public UserLikesMessage(){}
public UserLikesMessage(ApLikesBehavior data) {
super(data);
}
@Override
public String getType() {
return "user-likes";
}
}
修改 com.heima.behavior.service.impl.AppLikesBehaviorServiceImpl
@Override
public ResponseResult saveLikesBehavior(LikesBehaviorDto dto){
//.....上面代码省略.....
int temp = apLikesBehaviorMapper.insert(alb);
if(insert==1){
if(alb.getOperation()==ApLikesBehavior.Operation.LIKE.getCode()){
behaviorMessageSender.sendMessagePlus(new UserLikesMessage(alb),userId,true);
}else if(alb.getOperation()==ApLikesBehavior.Operation.CANCEL.getCode()){
behaviorMessageSender.sendMessageReduce(new UserLikesMessage(alb),userId,true);
}
}
return ResponseResult.okResult(temp);
}
(2) 阅读