首页 > 代码库 > java中使用FIFO队列:java.util.Queue实现多台服务器发邮件的代码

java中使用FIFO队列:java.util.Queue实现多台服务器发邮件的代码

代码下载地址:http://www.zuidaima.com/share/1838230785625088.htm

原文:java中使用FIFO队列:java.util.Queue实现多台服务器发邮件的代码

最近由于zuidaima.com注册用户的增多,qq企业邮箱发送邮件会被封禁账号导致注册后面的用户收不到周总结,所以紧急开发了一套多账号,多服务器发送邮件的程序。

大概的设计思路如下:

1.服务器可以无限扩展,但由于qq企业邮箱是限定域名,所以要想多服务器还得有多域名,多账号也不行。

2.最核心的代码是FIFO分配指定长度的邮件列表这一步,通过java线程同步Queue实现。

3.发送失败的要加到重试队列继续发送。

4.经测试每分钟发一封邮件,qq企业邮箱最大可以发送7000封邮件,这样最代码2个账号service@javaniu.com和service@zuidaima.com就可以发送到15000个邮件,该方案绝对是性价比超高的,目前市面上每封邮件1分钱,那15000也得150元人民币,如果你每周呢?

5.可以指定某个用户id来只发送某个范围的邮件列表

6.可以指定clear参数来清空所有邮件列表,不过该参数慎用,避免多发送邮件。

下面分享下核心代码,有思路和代码做参考,我想大家肯定可以自己搭建起来了:

分配邮件端核心java代码:

package com.zuidaima.mail;

private final static Map<Long, Queue<User>> map = new HashMap<Long, Queue<User>>();

// 申请发邮件的邮箱地址,每次根据mailTaskCount配置来取个数
	public @ResponseBody
	JSONObject apply_mails(
			@PathVariable("id") Long id,
			@RequestParam(value = http://www.mamicode.com/"start_date", required = false) String startDate,>

发送邮件端核心java代码:

package com.zuidaima.mail;

public static void main(String[] args) {
		if (args.length < 3) {
			System.out
					.println("需要3个参数:\n第一个是task id\n第二个是开始时间,如:2014-05-05\n第三个是结束时间,如:2014-05-09\n第四个参数user_id\n第五个参数是clear,如true");
			return;
		}

		String task_id = args[0];
		String start_date = args[1];
		String end_date = args[2];
		String user_id = "0";
		if (args.length >= 4) {
			user_id = args[3];
		}
		String clear = "";
		if (args.length >= 5) {
			clear = args[4];
		}
		String url = String.format(APPLY_EMAIL_URL, task_id, start_date,
				end_date, user_id, clear);
		while (true) {
			String response = request(url);
			JSONObject json = JSONObject.fromObject(response);
			String error = json.getString("error");
			if (StringUtils.isNotBlank(error)) {
				System.out.println("发送邮件结束:error:" + error);
				break;
			}

			JSONArray usersJson = json.getJSONArray("users");
			if (usersJson.size() == 0) {
				System.out.println("发送邮件结束");
				break;
			}
			String template = json.getString("template");
			String title = json.getString("title");
			int i = 1;
			try {
				List<JSONObject> failed1 = new ArrayList<JSONObject>();
				for (Object _userJson : usersJson) {
					send(_userJson, title, template, i, failed1,
							usersJson.size());
					i++;
				}
				if (failed1.size() == 0) {
					System.out.println("发送邮件结束一批");
					continue;
				}

				System.out.println("第一次发送失败的邮箱列表" + failed1);
				Thread.sleep(1 * 60 * 60 * 1000);
				List<JSONObject> failed2 = new ArrayList<JSONObject>();
				i = 1;
				for (Object userJson : failed1) {
					send(userJson, title, template, i, failed2, failed1.size());
					i++;
				}
				if (failed2.size() == 0) {
					System.out.println("failed1发送邮件结束一批");
					continue;
				}

				System.out.println("第二次发送失败的邮箱列表" + failed2);
				Thread.sleep(1 * 60 * 60 * 1000);
				List<JSONObject> failed3 = new ArrayList<JSONObject>();
				i = 1;
				for (Object userJson : failed2) {
					send(userJson, title, template, i, failed3, failed2.size());
					i++;
				}

				if (failed3.size() == 0) {
					System.out.println("failed2发送邮件结束一批");
					continue;
				}

				System.out.println("第三次发送失败的邮箱列表" + failed3);
				Thread.sleep(1 * 60 * 60 * 1000);
				List<JSONObject> failed4 = new ArrayList<JSONObject>();
				i = 1;
				for (Object userJson : failed3) {
					send(userJson, title, template, i, failed4, failed3.size());
					i++;
				}
				System.out.println("最终发送失败的邮箱列表:" + failed4);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

线上正式环境运行截图: